-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Error refactoring and exit code fixes #2046
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2046 +/- ##
==========================================
+ Coverage 71.72% 71.89% +0.16%
==========================================
Files 179 181 +2
Lines 14100 14116 +16
==========================================
+ Hits 10113 10148 +35
+ Misses 3349 3337 -12
+ Partials 638 631 -7
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
if errors.As(err, &ecerr) { | ||
// The given error already has an exit code, do nothing | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would never expect this to happen.
Is there a situation where that is a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use this property in https://github.com/k6io/k6/blob/1d741a854b1b18cd3af99f397d857375a630648c/cmd/run.go#L248-L252
The idea is that, since you're wrapping errors, you generally want to keep the most specific exit code possible. So having the WithExitCode
not overwrite an already existing attached error code is very helpful - in the above code, if we already had a an exit code (e.g. a script error) we'll exit with its code (e.g. 107
), but if we don't, we'd still attach a the more generic one there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, of course, you can always negate that with a custom error type (or another helper), if some other use case requires masking of a previously attached exit code. But this makes sense to me as the default behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am totally not sold on the "This is already wrapped in error fo the "same type" so I will silently not wrap it for you" idea. IMO w/e code will exit with the code should check whether it was wrapped multiple times and decide whether it should exit with the most inner one or not. Or for the code that is wrapping to check if it has ErrorCode and either wrap it again ... or not.
I am win with WithExitCodeIfNotOneAlready
being added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm fair enough... I am not sure if I should just rename this to WithExitCodeIfNotOneAlready
/ WithExitCodeIfNone
, since we don't really have a use case for something that always attaches an exit code yet, in most places it either doesn't matter (root errors deep in the code that first attach an exit code) or we don't want to overwrite it
alternatively, I can rip it out and only check for existing exit codes in a few places, I'll see how that looks like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ok? d8e41ec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cleaner than before, and I like the With*
and interfaces approach, but I'd prefer it if errext
wasn't a top-level package, but maybe cmd/errors
. There's really no reason an internal package should ever import it, and having it globally available suggests otherwise.
1d741a8
to
8771485
Compare
@imiric I tried to shuffle things around, but adding any more things to |
@na-- I doubt I'll be able to make progress if you haven't 😄 I'll take a look, but let's not delay merging this because of it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not going to "request changes", but I am still not on board with the whoever returns errors to say what the exit code should be.
I have left some other comments which mostly resolve around problems that I think raise from that.
if errors.As(err, &ecerr) { | ||
// The given error already has an exit code, do nothing | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am totally not sold on the "This is already wrapped in error fo the "same type" so I will silently not wrap it for you" idea. IMO w/e code will exit with the code should check whether it was wrapped multiple times and decide whether it should exit with the most inner one or not. Or for the code that is wrapping to check if it has ErrorCode and either wrap it again ... or not.
I am win with WithExitCodeIfNotOneAlready
being added
js/errors.go
Outdated
inner *goja.Exception | ||
} | ||
|
||
var _ errext.Exception = &scriptException{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably check for the HasHint
and HasErrorCode
while you are at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
although to be honest I am not certain if I wouldn't have preferred there to be newScriptExceiption()
which calls
WithHint(WithExitCode(scriptException{inner: ex}...))
On the other hand my biggest problem is that errext.ScriptException implementations can have different exitcodes ... which again is the whole problem with the exit codes being codified by whatever returns them instead of what will exit with them ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the other hand my biggest problem is that errext.ScriptException implementations can have different exitcodes
Well, that's not a bug, it's a feature. errext.ScriptException
means the error has a stacktrace, nothing less and nothing more. Exit codes are orthogonal to this. Theoretically, we might want to treat a script exception in handleSummary()
, for example, with a different exit code 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided not to wrap this in WithHint(WithExitCode())
, it didn't really improve things in terms of readability or clarity
0c4fbb1
to
b21b904
Compare
bbd2541
to
a7b85eb
Compare
This PR does a few things:
103
for script errors inVU>0
initialization, while preserving the helpful hintsk6 cloud
exit code from 99 to 97, to make it distinct from the already existing99
exit code fork6 run
(the k6 cloud code doesn't always mean that the thresholds have failed)