cli-error-notifier icon indicating copy to clipboard operation
cli-error-notifier copied to clipboard

Allow use of `stderr` inside the notifier message

Open 0x04 opened this issue 7 years ago β€’ 15 comments

It would be useful if there where a possibility to refer to the stderr in the notifier message. It could be archived with some replacement variable like ${error} or something like that.

0x04 avatar Mar 12 '18 18:03 0x04

I like the idea.

Two questions:

I’m not sure if we should truncate the stderr to make it fit into the notification message πŸ€” Does this makes sense? Because the available chars depends on the chars used for the message.

Should we use an easier to type placeholder? e.g. $error

mischah avatar Mar 12 '18 18:03 mischah

Hej @0x04, would you like to work on this?

mischah avatar Mar 13 '18 12:03 mischah

Well, that are good questions.

I'm thinking it makes no sense to truncate the stderr, because the length of message depends on the current OS.

My initial thought was that it would be nice to use the syntax of the template literal, but without getting interpreted it makes less sense. I think we should avoid the use of eval or new Function πŸ˜‚

@mischah Yeah, why not. Perhaps it is the best to start to experimenting with it, to see which procedure fits best.

0x04 avatar Mar 13 '18 14:03 0x04

After a lot of experimenting, I'm now thinking to do some evaluation on the error literal make sense. If we only put the stderr string in the message/title, this would pretty useless.

Im using new Function to create a independent context for executing the error literal content. This attempt allows to use the error object in the message and title string.

> # Just spit out the whole error message (calls the `toString` method)
> onerror "npm -e test" -t "Error!" -m "Message: {$error}"

> # Access properties of the error object
> onerror "npm -e test" -t "Error! Code ${error.code}" -m "Message: ${error.stderr.substr(0,10)}..."

> # Using a regexp to get a portion of the `stderr` (probably fails)
> onerror "npm -e test" -m "Message: ${error.stderr.match(/[\w\s]+:[\w\s]+\n/)[0]}

> # Making a regexp replace
> onerror "npm -e test" -m "Message: ${error.stderr.replace(/something/, function(m) { return 'somewhat'; })}

The implementation is checking against the error string, to avoid possible misuse. If you wonder why I extract the content of the error literal manually (errorLiteralPosition), it's cause the possibility of nested braces (inline functions etc.) and this is a hard job to do with RegExp. It's very basic and easy to break, but I don't want to include a whole JS parser to get this job done πŸ˜„

I'm just drop this lines, because im not sure if you're happy with this. Perhaps you have some comments or ideas on it. If we would use this approach, the template literal syntax would make sense, again 😏

0x04 avatar Mar 29 '18 12:03 0x04

@mischah Sorry, I forgot to ping you πŸ˜‚

0x04 avatar Apr 03 '18 14:04 0x04

@0x04 No problem.

Regarding your proposal: Wow 😳 This reads like a super advanced feature.

But to be honest. I’m scared that it’ll blow up the tiny little code base of that module. I’m not quite sure if the usefulness of the feature will compensate the growth of complexity of the codebase.

But I guess we will see 😊

mischah avatar Apr 03 '18 18:04 mischah

Yeah, the most heavy part of this is not the evalish interpretation of the literal itself. We have a very controlled environment. It's to detect to the portion itself. We could have strings, regexps, objects and functions with a opening/closing brace inside (and all other that I miss). While it's handable in general, it will blew up the code. I just did the most basic thing to play with it.

Well, it works - seems to be a useful tool, but I totally agree with the complexity that comes in. I think it could come very useful if you're using some kinda of IDE like Storm.

I will play around with it's possibilities, perhaps there's something that's less complex.

I will you inform on further progress @mischah!

0x04 avatar Apr 03 '18 19:04 0x04

Okay, I don't think this will make sense in this way of complexity. Closed for now, if I have a enlightment we can reopen it.

0x04 avatar Sep 05 '19 03:09 0x04

Thanks Oliver πŸ’–

mischah avatar Sep 05 '19 09:09 mischah

@mischah Good news, everyone!

I think I had some kind of enlightment! I just thought way to complicated.

Instead of parsing the message string to get the processing code for the ${error} variable, we could pass the this code through a new parameter. This is way easier than try to extract the JavaScript code portion from the message string.

# Old attempt
$ onerror "node -e test" -message "Error: \${error.toString()}"

# New attempt
$ onerror "node -e test" -message "Error: \${error}" -error "error.toString()"

The pseudo signature of the generated function for the error variable subsitution looks as follow:

function (error: object): string {
    return eval(opts.error);
}

The argument error is a childProcessResult Error. So we have access to all child process informations available. The default value for the parameter opts.error is "error.toString()" which just returns the command string.

Further that would allow some cool tweeks to the content of the ${error} variable.

$ onerror "node -e test" -message "\${error}" -error "`Code: \${error.code}`, Command: \${error.cmd.replace(/\r?\n/g, '⏎').substr(0, 15) + '...'}`"

Well, perhaps the processing code gets to long and hard to read - so we could use the power of bash to pass the contents of a JavaScript file:

$ onerror "node - test" -message "\${error}" -error "$(< errorMsg.js)"

Content of errorMsg.js e.g.:

(function(error) {
    const code = error.code;
    const cmd = error.cmd
        .replace(/\r?\n/g, '⏎')
        .substr(0, 15) + '...';

    return `Code: ${code}, Command: ${cmd}`;
})(error);

For Windows-Systems this is a bit harder. cmd isn't able to handle line breaks in variables - but you can assign the contents of a file to a variable. With PowerShell it's more bash-like.

cmd

rem cmd.exe
rem Assign file content to a variable and pass it to `onerror -e`
set /p error=<errorMsg_nolbr.js & onerror "node -e test" -m "${error}" -e "%error%"

PowerShell

# powershell.exe
onerror "node -e test" -m "`${error}" -e "$(type errorMsg.js)"

You can see my first implementation try on my latest commit. Would love to hear your thinking about it.

For now there's no error handling if the evaluation of the processing code fails. However I think it shouldn't be that hard to spit out some useful message to the cli.

Sorry for the shitload of text πŸ˜„

0x04 avatar Sep 10 '19 20:09 0x04

Hey I think you are mentioning me by mistake here.

On Tue, Sep 10, 2019 at 4:32 PM Oliver KΓΌhn [email protected] wrote:

@mischa https://github.com/mischa Good news, everyone!

I think I had some kind of enlightment! I just thought way to complicated.

Instead of parsing the message string to get the processing code for the ${error} variable, we could pass the this code through a new parameter. This is way easier than try to extract the JavaScript code portion from the message string.

Old attempt

$ onerror "node -e test" -message "Error: ${error.toString()}"

New attempt

$ onerror "node -e test" -message "Error: ${error}" -error "error.toString()"

The pseudo signature of the generated function for the error variable subsitution looks as follow:

function (error: object): string {

return eval(opts.error);

}

The argument error is a childProcessResult https://github.com/sindresorhus/execa#childprocessresult Error. So we have access to all child process informations available. The default value for the parameter opts.error is "error.toString()" which just returns the command string.

Further that would allow some cool tweeks to the content of the ${error} variable.

$ onerror "node -e test" -message "${error}" -error "Code: \${error.code}, Command: ${error.cmd.replace(/\r?\n/g, '⏎').substr(0, 15) + '...'}`"

Well, perhaps the processing code gets to long and hard to read - so we could use the power of bash to pass the contents of a JavaScript file:

$ onerror "node - test" -message "${error}" -error "$(< errorMsg.js)"

Content of errorMsg.js e.g.:

(function(error) {

const code = error.code;

const cmd = error.cmd

    .replace(/\r?\n/g, '⏎')

    .substr(0, 15) + '...';



return `Code: ${code}, Command: ${cmd}`;

})(error);

For Windows-Systems this is a bit harder. cmd isn't able to handle line breaks in variables - but you can assign the contents of a file to a variable. With PowerShell it's more bash-like.

cmd

rem cmd.exe rem Assign file content to a variable and pass it to onerror -e set /p error=<errorMsg_nolbr.js & onerror "node -e test" -m "${error}" -e "%error%"

PowerShell

onerror "node -e test" -m "${error}" -e ""$(type errorMsg.js)`""

You can see my first implementation try on my latest commit. Would love to hear your thinking about it.

For now there's no error handling if the evaluation of the processing code fails. However I think it shouldn't be that hard to spit out some useful message to the cli.

Sorry for the shitload of text πŸ˜„

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/micromata/cli-error-notifier/issues/7?email_source=notifications&email_token=AAADKFLURFFPBQJXFYWDHWLQI776FA5CNFSM4EU4RQL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6MMXVQ#issuecomment-530107350, or mute the thread https://github.com/notifications/unsubscribe-auth/AAADKFIWQ4Z2YK3WIGSV6EDQI776FANCNFSM4EU4RQLQ .

mischa avatar Sep 10 '19 21:09 mischa

Yeah, sorry for that. I forgot a h in the end of mischah's nickname.

0x04 avatar Sep 10 '19 22:09 0x04

Hej @0x04,

it still sound complicated to me πŸ˜…

You can see my first implementation try on my latest commit.

Where? Maybe it would make sense to open a Β»WIPΒ« PR?

Thanks a bunch πŸ’–

mischah avatar Sep 13 '19 14:09 mischah

Hi @mischah,

created a »WIP« PR as suggested. I hope I did it right 🀞

0x04 avatar Sep 13 '19 16:09 0x04

Thanks. Hope to find some time to review this pretty soonish 😊

mischah avatar Sep 17 '19 16:09 mischah