Closed
Bug 1219852
Opened 9 years ago
Closed 9 years ago
unwrap common error types when reporting rejected respondWith() promise
Categories
(Core :: DOM: Service Workers, defect)
Core
DOM: Service Workers
Tracking
()
RESOLVED
FIXED
mozilla45
People
(Reporter: bkelly, Assigned: bkelly)
References
Details
Attachments
(2 files, 2 obsolete files)
(deleted),
patch
|
bkelly
:
review+
ritu
:
approval-mozilla-aurora+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
bkelly
:
review+
ritu
:
approval-mozilla-aurora+
|
Details | Diff | Splinter Review |
When we report a rejected respondWith() promise we currently just use nsAutoJSString::Init() to do the conversion from JSVAlue. This will give us [Object object] for a lot of common errors. We should unwrap DOMException and Error at least.
Assignee | ||
Comment 1•9 years ago
|
||
Try to unwrap DOMException and Error, otherwise just convert primitives to strings.
Attachment #8681479 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 2•9 years ago
|
||
Attachment #8681480 -
Flags: review?(bzbarsky)
Assignee | ||
Updated•9 years ago
|
Blocks: ServiceWorkers-v1
Assignee | ||
Comment 3•9 years ago
|
||
Note, P2 has string changes. Unfortunately I missed the somewhat-common error where a script passes a non-Response, like null or undefined, to .respondWith().
Assignee | ||
Comment 4•9 years ago
|
||
Comment 5•9 years ago
|
||
Comment on attachment 8681479 [details] [diff] [review]
P1 Unwrap common JS values for reject respondWith() promises. r=bz
So this isn't so much "unwrapping" the values (which makes it sounds like we're talking security wrappers or reflectors) but trying to extract file/line/column/message from them in a way that has no side-effects, right?
Not sure that good naming is for that.
>+ aSourceSpecOut.Assign(nsDependentCString(err->filename));
Can you not just Assign(err->filename)?
>+ aMessageOut.Assign(NS_LITERAL_STRING("Error: "));
It might be a TypeError or whatnot. You can look at report->exnType to get that information, right?
It's hard to believe we don't already have something like this code hanging around, but making it reusable here might be more pain than just doing this for now.
>+ else if(NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException)) &&
>+ domException) {
UNWRAP_OBJECT succeeds if and only if it sets the third arg to non-null. So no need for the null-check.
>+ domException->GetMessageMoz(aMessageOut);
Is there a reason to not grab the filename/linenumber/column from the DOMException?
>+ if (jsString.init(aCx, aValue)) {
And if not, you want to JS_ClearPendingException(aCx), right?
r=me with those nits.
Attachment #8681479 -
Flags: review?(bzbarsky) → review+
Comment 6•9 years ago
|
||
Comment on attachment 8681480 [details] [diff] [review]
P2 Report non-respond values passed to FetchEvent.respondWith(). r=bz
r=me
Attachment #8681480 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 7•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #5)
> >+ if (jsString.init(aCx, aValue)) {
>
> And if not, you want to JS_ClearPendingException(aCx), right?
How does the context get a pending exception here? I am extracting the string from a Promise provided value, not an exception off the stack.
Flags: needinfo?(bzbarsky)
Assignee | ||
Comment 8•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #5)
> >+ aMessageOut.Assign(NS_LITERAL_STRING("Error: "));
>
> It might be a TypeError or whatnot. You can look at report->exnType to get
> that information, right?
>
> It's hard to believe we don't already have something like this code hanging
> around, but making it reusable here might be more pain than just doing this
> for now.
I switched to using xpc::ErrorReport to do the message formatting for me.
> >+ domException->GetMessageMoz(aMessageOut);
>
> Is there a reason to not grab the filename/linenumber/column from the
> DOMException?
Added code to extract them if the filename is set on the exception.
Also, I changed the message to be "<name>: <message>". For example, "NotFoundError: node not found". I think this makes the error messages a bit easier to understand.
Assignee | ||
Comment 9•9 years ago
|
||
Attachment #8681479 -
Attachment is obsolete: true
Attachment #8681616 -
Flags: review+
Assignee | ||
Comment 10•9 years ago
|
||
Attachment #8681480 -
Attachment is obsolete: true
Attachment #8681617 -
Flags: review+
Comment 11•9 years ago
|
||
Assignee | ||
Comment 12•9 years ago
|
||
Landed on inbound so I have some hope of getting the new string into 44 aurora. If the JS_ClearPendingException() thing turns out to be a real issue I will fix in a follow-up.
Assignee | ||
Comment 13•9 years ago
|
||
Comment on attachment 8681616 [details] [diff] [review]
P1 Extract common JS values for rejected respondWith() promises. r=bz
Uplift request for P1 and P2.
Approval Request Comment
[Feature/regressing bug #]: Service workers
[User impact if declined]: Needed to provide reasonable error reporting for web developers using service workers. Necessary if we decide to ship in 44 and would be nice to have in our promoted dev edition.
[Describe test coverage new/current, TreeHerder]: Existing mochitests pass and do not show any regressions. I tested actual reporting output locally.
[Risks and why]: Minimal. Only effects service workers.
[String/UUID change made/needed]: One new string for reporting a very common service worker interception problem. This should land in m-c before the original string freeze for 44.
Attachment #8681616 -
Flags: approval-mozilla-aurora?
Comment 14•9 years ago
|
||
> How does the context get a pending exception here?
If nsAutoJSString::init returned false, that means we hit OOM somewhere under it: either linearizing an existing JSString, or allocating the XPCOM string to copy into (under AssignJSString) or allocating a JSString to represent the non-string value we passed in. In all those cases an OOM exception will be set on the JSContext. In other words, the pending exception is because nsAutoJSString::init threw it.
This is the general pattern of JSAPI and like methods that take a JSContext and return bool success vs failure: false means there is now an exception on the JSContext.
In this case you want to just do the equivalent of catching that exception, because there's not much else you can do with it.
> I switched to using xpc::ErrorReport to do the message formatting for me.
Ah, excellent. I like that much more. ;)
> Added code to extract them if the filename is set on the exception.
Looks good, though in practice filename will in fact be empty if !NS_SUCCEEDED, so you could just do the GetFilename without checking its retval, then check !filename.IsEmpty().
Flags: needinfo?(bzbarsky)
Assignee | ||
Comment 15•9 years ago
|
||
Hmm, NI myself to file a follow up on exception issue. Note, though, there are many other places in the tree which do not clear the exception either. So this may be a more widespread problem.
Assignee | ||
Updated•9 years ago
|
Flags: needinfo?(bkelly)
Assignee | ||
Comment 16•9 years ago
|
||
Boris, are all these callers of nsAutoJSString::init() wrong too, then?
https://dxr.mozilla.org/mozilla-central/search?q=%2Bcallers%3A%22nsAutoJSString%3A%3Ainit%28struct+JSContext+*%2C+const+JS%3A%3AValue+%26%29%22
I don't see any of them clearing the pending JS exception.
Flags: needinfo?(bzbarsky)
Comment 17•9 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/461594bb8ab7
https://hg.mozilla.org/mozilla-central/rev/255266023178
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla45
Comment 18•9 years ago
|
||
> Boris, are all these callers of nsAutoJSString::init() wrong too, then?
Looking at those callsites:
1) nsContentPermissionRequestProxy::Allow is in fact busted. It's busted in other ways too: e.g. if !JS_GetProperty it's also leaving a dangling exception on the JSContext.
2) nsAutoJSString::init (the value-only version) is imo also busted. The context is used for more than just rooting, obviously.
3) nsAutoJSString::init, the jsid version, is not a problem per se: it just propagates things up to the caller. Looking at its callers, GetPropertyValuesPairs is correct: it just propagates the exception up to the caller. nsGeolocationSettings::HandleGeolocationPerOriginSettingsChange is broken because it presses on with the loop instead of breaking out of it, and similarly broken for its JS_GetPropertyById and JS_GetProperty calls. If it broke out of the loop immediately, it would be ok, since it then reports the exception from the JSContext before returning.
4) nsGeolocationSettings::HandleGeolocationAlwaysPreciseChange is broken for the same reasons.
5) Key::EncodeJSValInternal is ok as far as it goes: it returns error immediately on this false return. It's called from itself and from Key::EncodeJSVal. The latter is called from SetFromJSVal and AppendItem. The callers of AppendItem are _almost_ OK except the KeyPath::ExtractOrCreateKey one that sometimes turns the retval into NS_OK: that one should clear the exception on aCx (though it's possible we never reach this code in that situation where value is undefined). Also, I didn't trace every single IDB codepath here all the way to its entrypoint; there are lots of them. So it's possible there's more bogosity hiding up-stack.
6) nsJSThunk::EvaluateScript is fine: it returns immediately on failure, and has taken ownership of error reporting on the AutoEntryScript, so reports the exception at that return point.
7) RespondWithHandler::RejectedCallback (before the changes in this bug, looks like) is broken.
8) JavaScriptShared::toVariant returns false on init failure. I'm not sure what it's callers do with it; there are a ton of them, but mostly they propagate the failure on to ... somewhere. WrapperAnswer::fail is a bit suspicious in that it ignores the return value, but a quick look at its callers suggests they all TakeOwnerShipOfErrorReporting on the AutoJSAPI objects they pass it, and fail() is always used like |return fail(...)| so these callers are ok.
9) JSKeyedHistogram_Add is ok: on false return it tries to throw on the JSContext anyway, so if there is an exception there already either it will stay or get replaced but the end state is the same: a JSContext with an exception on it. It then returns false to caller to signal the exception.
10) KeyedHistogram_SnapshotImpl same thing as JSKeyedHistogram_Add.
Flags: needinfo?(bzbarsky)
Comment 19•9 years ago
|
||
> nsContentPermissionRequestProxy::Allow is in fact busted.
Filed bug 1220679.
> nsAutoJSString::init (the value-only version) is imo also busted.
Bug 1220682.
> nsGeolocationSettings::HandleGeolocationPerOriginSettingsChange is broken
> nsGeolocationSettings::HandleGeolocationAlwaysPreciseChange is broken
Bug 1220688.
Assignee | ||
Comment 20•9 years ago
|
||
Filed bug 1220728 to fix review issues from comment 14.
Flags: needinfo?(bkelly)
Comment 21•9 years ago
|
||
bugherder uplift |
https://hg.mozilla.org/releases/mozilla-b2g44_v2_5/rev/461594bb8ab7
https://hg.mozilla.org/releases/mozilla-b2g44_v2_5/rev/255266023178
status-b2g-v2.5:
--- → fixed
Comment 22•9 years ago
|
||
removing the b2g 2.5 flag since this commit has been reverted due to an incorrect merge, sorry for the confusion
status-b2g-v2.5:
fixed → ---
Comment on attachment 8681616 [details] [diff] [review]
P1 Extract common JS values for rejected respondWith() promises. r=bz
This landed on Nightly a week ago, let's uplift to Aurora44.
Attachment #8681616 -
Flags: approval-mozilla-aurora? → approval-mozilla-aurora+
Comment on attachment 8681617 [details] [diff] [review]
P2 Report non-response values passed to FetchEvent.respondWith(). r=bz
This one too.
Attachment #8681617 -
Flags: approval-mozilla-aurora+
Comment 25•9 years ago
|
||
bugherder uplift |
Comment 26•9 years ago
|
||
bugherder uplift |
https://hg.mozilla.org/releases/mozilla-b2g44_v2_5/rev/2894bcec3447
https://hg.mozilla.org/releases/mozilla-b2g44_v2_5/rev/77efb8bcd129
status-b2g-v2.5:
--- → fixed
You need to log in
before you can comment on or make changes to this bug.
Description
•