Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config.fatal now throws an exception #357

Merged
merged 1 commit into from
Feb 16, 2016
Merged

Conversation

jrmclaurin
Copy link
Contributor

Hi everyone!

This PR adds a 'config.throw' option to throw errors from shell commands. Config.fatal is useful, but it doesn't log stack traces, which makes deep errors hard to find. This 'throw' option is useful in synchronous scripts where you have try / catch handling, or you want the default behavior of printing a full stack trace and exiting.

Thanks!!

@nfischer
Copy link
Member

@jrmclaurin did you make your README changes in the file that the README is generated from? I think it's shell.js.

@ariporad what do you think of this? I don't like having 2 options for basically the same thing. Maybe throwing is better behavior? So we could change config.fatal to throw an exception, and let config.fatal & config.silent to silently exit with an error code. Just a thought, not sure if this would be an issue.

Update: I originally said config.error, when I really meant config.fatal

@jrmclaurin
Copy link
Contributor Author

Hi @nfischer, I hadn't noticed that README was generated, so I updated it directly. Sorry about that.

@nfischer
Copy link
Member

Could you move the changes to the file its generated from? Otherwise CI won't pass. The issue is that regenerating docs will just wipe out your changes, which isn't what we want

@ariporad
Copy link
Contributor

I say we make config.fatal just do this. I can't see any reason why that
would
be bad.

@nfischer
Copy link
Member

@jrmclaurin would you be able to refactor config.fatal?

@jrmclaurin
Copy link
Contributor Author

@nfischer Sure thing, I'll do that refactor, and put the docs in the right place. Thanks!!

@nfischer
Copy link
Member

Awesome! Thanks, @jrmclaurin! If you can, please squash your commits when finished (or we can do that for you, if you prefer). This should be a good addition

@jrmclaurin
Copy link
Contributor Author

OK @nfischer, I refactored to change the behavior of config.fatal, and update unit tests to match. I believe I squashed the commits correctly, but let me know if I did anything wrong. Thanks everyone for your open-mindedness about this issue!

@jrmclaurin
Copy link
Contributor Author

I forgot about @nfischer's suggestion to exit silently if both config.fatal and config.silent are set. This is a bit of conjecture, but if someone sets both config.silent and config.fatal, they probably want config.silent to eliminate console noise when everything's OK, but they'll expect config.fatal to still throw when an error happens. So should we leave it like it is (fatal always throws), and anyone who wants "silent fatal" behavior can wrap their code in try / catch and swallow errors? Making config.fatal stronger than config.silent seems like the safer choice.

@nfischer
Copy link
Member

As it is, the only time commands output to the console is for errors (and for echo() statements). config.silent actually only suppresses error messages, not echo() commands (although I think this should be changed, but that's just my opinion). So that's why I was thinking it should be like config.fatal's current behavior, since config.silent functions to suppress error messages.

That's just a thought though, and I don't mind much one way or another, since I don't think backward compatibility in this sense is terribly important. The try-catch approach is also good for suppressing errors, and having one approach probably makes things a little cleaner.

assert.equal(result.stdout, '');
assert.equal(result.stderr, 'ls: no such file or directory: file_doesnt_exist\n');
assert(result.stderr.indexOf('Error: ls: no such file or directory: file_doesnt_exist') >= 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have "Error: " prepended to the front?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of directly printing the message to stderr, we're now throwing an Error, so we end up at node's uncaught error handling. That's why you end up with "Error:" in front of the message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, makes sense. Sounds good

@jrmclaurin
Copy link
Contributor Author

OK, I made that node.js version check in test/set.js actually work right :-)

assert.throws(function() {
shell.exec('asdfasdf'); // could not find command
}, function(err) {
return err.message === 'exec: internal error';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. I'm pretty sure you can just pass in the expected error message here, and it will compare.
  2. Is there any way to make the error message a little more descriptive?

@ariporad
Copy link
Contributor

Looks good,but I have one small nitpick.

@jrmclaurin
Copy link
Contributor Author

@ariporad You were right that assert.throws can just look at the message, so I made that change. Do you want a more detailed message when I'm creating the Error? I can't think of anything else I could put in there that would be helpful.

@ariporad
Copy link
Contributor

@jrmclaurin: I was thinking something like "Command not found"

@jrmclaurin
Copy link
Contributor Author

@ariporad Good point--I hadn't realized that the error message from the command isn't making it into the thrown error. To fix that problem, it looks like src/exec.js would need to scrape some stderr and / or stdout, and stuff it in the message that's being sent to common.error. Here's the scene of the crime, src/exec.js line 151:

if (code !== 0) {
common.error('', true);
}

@ariporad
Copy link
Contributor

@jrmclaurin: Ok. I'm working on re-doing exec, so don't worry.

LGTM!

@ariporad
Copy link
Contributor

@nfischer: feel free to merge.

@nfischer
Copy link
Member

I'll test this out today and merge if I have no issues

@nfischer nfischer changed the title Add 'throw' option to config. config.fatal now throws an exception Feb 16, 2016
@nfischer
Copy link
Member

LGTM! I renamed the PR to better describe the change that's being merged, since it's deviated a bit from the original intent. Thanks, @jrmclaurin!

nfischer added a commit that referenced this pull request Feb 16, 2016
config.fatal now throws an exception
@nfischer nfischer merged commit 0da963b into shelljs:master Feb 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants