-
Notifications
You must be signed in to change notification settings - Fork 165
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
Handle exceptions when calling callbacks by default #1423
Comments
This carries out the first portion of the plan in #958 (comment), by creating a new "report an exception" algorithm that replaces the previous "report an error" and "report the exception". The new algorithm directly includes the error propagation and fallback behavior, and requires callers to supply the global object to be used, rather than magically inferring it. It no longer takes a script, since in most cases the script was not rigorously determined. Follow-up work on determining the correct muting behavior (which the script argument was used for) is tracked in #10514. All call sites within HTML are updated. #10516 tracks updating call sites in other specifications. In most cases the global used for HTML is now specified rigorously and matching implementations. #10526 and #10527 track the remaining cases with interop issues. Closes #958, with the rest of the plan there tracked via the issues mentioned above, whatwg/webidl#1423, and the https://github.com/whatwg/html/labels/topic%3A%20error%20reporting label.
A survey of the current uses of these algorithms indexed by webdex. Note that promise-returning callback types cannot actually throw, because WebIDL turns this into a promise rejection internally.
Excluded from this list are references which do not invoke these algorithms (but mention or modify it). The "catch and report" cases naturally don't specify the global (except HTML, where this was part of whatwg/html#10404). It's likely that the callback's realm's global is appropriate, though for each a cursory check of existing browser behavior would be nice. WebIDL also doesn't have many normative references to HTML. This wouldn't be the first, though. Do you still think this should be a boolean defaulting to reporting, or should this be a required parameter? Or maybe some kind of conditionally required parameter, where it must be specified unless it's a promise-returning callback? |
Wow, amazing work; thank you.
This needs to catch and report, I think? Right now the error just goes to the top level of the task, which is... undefined behavior?
I'd really like us to be able to use the same answer for all cases and not have this be configurable per call site. But yeah, agreed that a check would be good.
I hadn't thought a conditionally-required parameter before. Maybe that's the way to go, if we're changing all the call sites anyway. Reporting-by-default makes "invoke" and friends require fewer brains to use; if you told me there was a Web IDL algorithm called "invoke" for callbacks I might just call it without thinking to look up if it had extra arguments. But if we can assume that all spec writers look up the signatures of the algorithms they use, then probably it's better. And I think that's a ... reasonable? ... assumption. In that case I'd change from a boolean to something like "report" vs. "rethrow". I was wondering if we could do "report-and-rethrow" for the cases that report but also do custom behavior. But I feel like probably in those cases you want to do the custom behavior first, before potentially running author code? (Although at least one place does not do that right now... I wonder if that's a bug.) I don't know; if there were a way to make it easier to ensure that people always send it to the right global for a callback after doing their custom processing, that would be nice. Let me know if you have an yideas. For how to do "conditionally-required", I'd do something like
The other strategy I thought of was declaring it as optional with a default of "promise", and then using an Assert to state that it's not left as the default for non-promise _callable_s. However, this has the disadvantage that someone skimming the algorithm declaration might think it was actually optional. |
Agreed, it should probably report. Updated the table.
Agreed, though if that is not what browsers do then we have to get vendors to change it, assuming doing so would be web-compatible. I'm hoping that it's either already doing that everywhere or it's easy to fix.
There are few enough sites and they're special enough already that I think complicating WebIDL to handle them is probably not worthwhile. And hopefully the number of such sites doesn't grow too much.
I had those exact same two thoughts and typed both of them in a response before noticing you'd described exactly the same things. (also, bikeshed: exceptionBehavior vs exceptionHandling?) |
Another quick question -- in the report case, what happens if the return type is not Edit: Converting undefined to a type can itself throw, and that isn't handled above. Fun. |
Also, since all call sites of construct and call a user object's operation do something special, I'm leaving them alone for now. Construct, in particular, can't just report and return nothing because callers are definitely going to be expecting a result. |
This makes it more concise for users to, as is frequently desired for undefined-returning callbacks especially, immediately catch and report the exception rather than needing to handle it themselves. This isn't appropriate for other types of callback functions, where a result may be expected or the exception needs to be rethrown. Callers need to explicitly decide which behavior they want, unless the callback returns a promise type, in which case exceptions are turned into rejected promises implicitly. Fixes whatwg#1423.
(Agreed on all the decisions you made regarding return types, construct, and call a user object's operation.) @jeremyroman are you up for turning your table in #1423 (comment) into a checklist, now that we know which cases need mandatory updates? Probably create a new tracking issue in this repo. |
…2aff51d86 全面改革异常报告算法 此更改执行了 #958(评论)中计划的第一部分,创建了一个新的“报告异常”算法,取代了之前的“报告错误”和“报告异常”。 新算法直接包括了错误传播和回退行为,并要求调用者提供要使用的全局对象,而不是通过某种方式自动推断。它不再接受脚本参数,因为在大多数情况下,脚本并未被严格确定。后续工作将着重于确定正确的静音行为(脚本参数曾用于此),并在 #10514 中进行跟踪。 HTML 中的所有调用点都已更新。#10516 用于跟踪在其他规范中更新调用点。在大多数情况下,HTML 使用的全局对象现在已被严格指定,并与实现相匹配。#10526 和 #10527 用于跟踪具有互操作性问题的剩余情况。 #958 已完成,剩余计划将通过上述提到的问题、whatwg/webidl#1423 和 [https://github.com/whatwg/html/labels/topic%3A%20error%20reporting](https://github.com/whatwg/html/labels/topic%3A%20error%20reporting) 标签进行跟踪。
What is the issue with the Web IDL Standard?
Splitting from whatwg/html#958 (comment).
After whatwg/html#10404 lands, HTML will have a solid foundation for reporting exceptions.
It turns out that most cases, when spec writers use Web IDL to construct or invoke callback functions, or to call a user object's operation, they want errors to be reported to the global error handler; they don't want them to propagate out. Such reporting is a safer default.
We should add a new optional named parameter rethrowExceptions (default false) to these definitions. When it is false, we introduce the following new behavior: any exceptions thrown by web developer code get caught and routed to HTML's new "report the exception". ("Web developer code" is roughly everything between the "prepare" and "cleanup" steps, including both argument conversion and the actual code invocation.)
Which global do we propagate to? @jeremyroman's research in whatwg/html#10404 settled on the JavaScript function object's realm's global object.
Before merging this change, however, we need to have PRs ready for all call sites of construct/invoke/call a user object's operation, to prepare them for the new default. In most cases this will be deleting some spec code that try/catches the exception and reports it. So, this will be a multi-spec project.
We can use these links to find all callers:
The text was updated successfully, but these errors were encountered: