-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
create single path for handling errors from the protocol #977
Conversation
to be clear, this does not handle the main part of #976, dealing with |
error = error || {message: 'Unknown debugger protocol error.'}; | ||
|
||
const callback = { | ||
resolve, |
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.
the use of new Promise
now feels pretty weird here since we're basically passing both resolve and reject to another function, thoughts on Promise.try
or the stop-gap Promise.resolve().then
instead and just having handleRawError
return its own promise?
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.
ah, I like it. This is kind of awkward because of the raw connection setup, but that should work for both
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 haven't run into (too many) issues using the Promise.resolve().then
pattern Patrick suggested above, so a 👍 to switching over to that and letting handleRawError
do it's bizness.
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.
ah, I wasn't going to do that part :) I'll consider it, but we use resolve(result);
farther down in that function. It is a simplistic use of a promise, but I don't really mind resolve
vs return
, and exceptions are treated the same way. I'm sure others feel otherwise :)
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.
incidentally, this is one more reason we need to always avoid Promise.all
ing any debugger protocol code since any refactor like this might introduce ticks between steps, even in driver functions that only run a single command :)
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.
ok, the more I think about it, the more I like this pattern. I had avoided it in the past just because the `Promise.resolve() part feels like a waste (and the extra tick from it can be an issue for reasoning about things running in parallel), but the consistency in code is pretty nice. I'd be in favor of adopting this pattern in the future for functions returning a promise but also needing to swallow sync exceptions.
We need to be careful converting old code, though, because I know there are a few places we've written code explicitly assuming the executor will be executed synchronously (which is actually one more point in the consistency column if we always assume this pattern)
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'd be in favor of adopting this pattern in the future for functions returning a promise but also needing to swallow sync exceptions.
👏
const message = chrome.runtime.lastError.message; | ||
let error; | ||
try { | ||
error = JSON.parse(message); |
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.
more just an aside here, i've had to do this a couple times in the past too and always thought there had to be a better way i was missing, i guess not? haha
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.
ha, yeah. The docs on lastError
are really unhelpful. Not only is message
marked optional, there's no hint of what the format of the error is, it's just always JSON when I try it...
updated, PTAL |
d2d3dc7
to
0c549d0
Compare
error = error || {message: 'Unknown debugger protocol error.'}; | ||
|
||
// handleRawError returns or throws synchronously, so try/catch awkwardly. | ||
try { |
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'm guessing chrome.debugger.sendCommand
doesn't return a promise? otherwise we could follow the earlier pattern
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.
no, only callback
0c549d0
to
835ce37
Compare
835ce37
to
c8d7556
Compare
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.
LGTM with the suggestions
* about and throwing on the rest. | ||
* @param {{message: string}} error | ||
* @param {string} method Protocol method that received the error response. | ||
* @protected |
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.
Should this stay underscored if it's meant to be @protected
?
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.
Add a @throws
?
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.
no, no underscore for @protected
(not that closure is looking at this, really only annotating to keep in the style of the rest of the file)
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.
Add a @throws
done
* @param {{error: {message: string}}} object | ||
* @param {{reject: function(*), method: string}} callback | ||
* @private | ||
* Handles error responses from the protocol, absorbing errors we don't care |
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.
absorbing errors we don't care...
it's only the DOM.disable atm.
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.
done
c8d7556
to
41e9354
Compare
return resolve(this.handleRawError(error, command)); | ||
} catch (err) { | ||
return reject(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.
This pattern is a little awkward (as noted) but I think I prefer this flavor to what we had here before.
Waiting for travis to complete a run on your last set of commits, but looks like it's all good to go. |
…e#977) * create single path for handling errors from the protocol * make handleRawError synchronous
starts addressing #976
also gives slightly more context for errors like #966 (as well as a real stack trace)
Moves the extension and the raw connection to use the same error handler for messages coming back from the debugging protocol, as well as normalizing the error object fed into it. This should aid debugging. Happens to unify catching of
DOM.disable
error, instead of in separate spots for extension and CLI.Also removes old
result.wasThrown
from extensionsendCommand
, which as discussed in #976 was doing nothing but confusing us.