Detect unhandled promise rejections
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 25/100
- Tipo de issue
- Funcionalidade
- Clareza
- Razoavelmente clara
- Status de atividade
- Estagnada
- Stack de tecnologia
- javascript, ruby
Direção de pesquisa
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.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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>
- Linguagem predominante
- JavaScript
- Estrelas
- 628
- Forks
- 100
- Merge médio
- 1d 20h
- PRs com merge (30d)
- 2
Preparar o ambiente
- Inclui um Dockerfile ou arquivo Docker Compose
- Sem modelo de pull request
- Sem guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de rubyjs/mini_racer
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
rubyjs/mini_racer#449 ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 52/100
rubyjs/mini_racer#450 ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 52/100
rubyjs/mini_racer#448 ·
-
bug/crash platform: linux/x86
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 42/100
rubyjs/mini_racer#422 · 10 comentários ·
-
platform: darwin/x86
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
rubyjs/mini_racer#388 · 4 comentários ·
Todas as issues de rubyjs/mini_racer
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 72/100
thedevs-network/kutt#1059 ·
-
good first issue help wanted
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 82/100
Mantenedores costumam responder em até 1 dia
-
0. Needs triage 35-feedback bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
Mantenedores costumam responder em até 1 dia