Detect unhandled promise rejections
還沒有人認領這個 Issue。
評估
- 難度
- 5/5
- 預估耗時
- 一週以上
- 新手友好度
- 25/100
- Issue 類型
- 功能
- 描述清晰度
- 基本清楚
- 活躍度
- 停滯
- 技術堆疊
- javascript, ruby
研究方向
The issue points to V8's SetPromiseRejectCallback and PromiseRejectMessage; start by reading those API definitions and locating how mini_racer connects V8 callbacks to Ruby exceptions. The example shows the missed rejection and the expected error behavior, while the issue leaves the default behavior and configurability undecided. Done means unhandled rejections are reported to Ruby, with the handling behavior defined.
由索引模型根據 Issue 內容生成。
描述
When working with promises, one important aspect of them is that an unhandled rejected promise is an error. However, V8 will drop notifications by default.
I think that mini_racer should consider this an error and raise an exception, though possibly it should be configurable how these are handled (e.g. via a callback where the user can decide to re-raise?).
To do so, it's necessary to register for unhandled promise rejections via SetPromiseRejectCallback.
The callback will receive a PromiseRejectMessage that should probably (by default) raise a exception in ruby, although I suppose it could be configurable.
Comparisons for reference:
Running this code:
var x = async () => { throw "failure"; };
var y = async () => { x() /* ignore the rejected result */ };
y().then(() => console.log("done")).catch(e => console.log(e));
In node:
> var x = async () => { throw "failure"; }; var y = async () => { x() /* ignore the rejected result */ }; y().then(() => console.log("done")).catch(e => console.log(e));
Promise {
<pending>,
domain:
Domain {
domain: null,
_events:
{ removeListener: [Function: updateExceptionCapture],
newListener: [Function: updateExceptionCapture],
error: [Function: debugDomainError] },
_eventsCount: 3,
_maxListeners: undefined,
members: [] } }
> done
(node:83056) UnhandledPromiseRejectionWarning: failure
(node:83056) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
In chrome:
var x = async () => { throw "failure"; }; var y = async () => { x() /* ignore the rejected result */ }; y().then(() => console.log("done")).catch(e => console.log(e));
VM131:1 done
Promise {<resolved>: undefined}
VM131:1 Uncaught (in promise) failure
In mini_racer:
irb(main):001:0> require 'mini_racer'
=> true
irb(main):002:0> vm = MiniRacer::Context.new
=> #<MiniRacer::Context:0x00007ff4350f1438 @functions={}, @timeout=nil, @max_memory=nil, @current_exception=nil, @isolate=#<MiniRacer::Isolate:0x00007ff4350f12f8 @lock=#<Thread::Mutex:0x00007ff4350f12a8>>, @disposed=false, @callback_mutex=#<Thread::Mutex:0x00007ff4350f1280>, @callback_running=false, @thread_raise_called=false, @eval_thread=nil>
irb(main):003:0> vm.attach('console.log', proc{ |*args| puts('LOG> ' + args.map(&:to_s).join(' ')) })
=> #<MiniRacer::Context::ExternalFunction:0x00007ff43602b1b0 @name="log", @callback=#<Proc:0x00007ff43602b200@/usr/local/lib/ruby/gems/2.5.0/gems/mini_racer-0.1.15/lib/mini_racer.rb:201 (lambda)>, @parent=#<MiniRacer::Context:0x00007ff4350f1438 @functions={"console.log"=>#<MiniRacer::Context::ExternalFunction:0x00007ff43602b1b0 ...>}, @timeout=nil, @max_memory=nil, @current_exception=nil, @isolate=#<MiniRacer::Isolate:0x00007ff4350f12f8 @lock=#<Thread::Mutex:0x00007ff4350f12a8>>, @disposed=false, @callback_mutex=#<Thread::Mutex:0x00007ff4350f1280>, @callback_running=false, @thread_raise_called=false, @eval_thread=nil>, @parent_object_eval="if (typeof console === 'undefined') { console = {} };\nconsole;", @parent_object="console">
irb(main):004:0> vm.eval('var x = async () => { throw "failure"; }; var y = async () => { x() /* ignore the rejected result */ }; y().then(() => console.log("done")).catch(e => console.log(e));')
LOG> done
=> {}
irb(main):005:0>
- 主要語言
- JavaScript
- 星號
- 628
- 分支
- 100
- 平均合併
- 1 天 20 小時
- 30 天內合併 PR
- 2
環境準備
- 提供 Dockerfile 或 Docker Compose 檔案
- 沒有 Pull Request 範本
- 沒有貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
rubyjs/mini_racer 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 76/100
rubyjs/mini_racer#449 ·
-
難度 4/5 3-5 天 新手友好度 52/100
rubyjs/mini_racer#450 ·
-
難度 4/5 3-5 天 新手友好度 52/100
rubyjs/mini_racer#448 ·
-
bug/crash platform: linux/x86
難度 4/5 3-5 天 新手友好度 42/100
rubyjs/mini_racer#422 · 10 則留言 ·
-
platform: darwin/x86
難度 4/5 3-5 天 新手友好度 35/100
rubyjs/mini_racer#388 · 4 則留言 ·
查看 rubyjs/mini_racer 的全部 Issue
相似的 Issue
-
status: waiting for maintainer
難度 2/5 1-3 小時 新手友好度 74/100
mui/material-ui#49547 ·
維護者通常 1 天內回覆
-
[2.x] extension-manager: translation keys that changed meaning keep their old names可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉type/bug
難度 2/5 1-3 小時 新手友好度 84/100
維護者通常 1 天內回覆
-
難度 1/5 1 小時以內 新手友好度 66/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 67/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 72/100
rescript-lang/rescript#8996 ·
維護者通常 1 天內回覆