async_wrap: notify post if intercepted exception
The second argument of the post callback is a boolean indicating whether the callback threw and was intercepted by uncaughtException or a domain. Currently node::MakeCallback has no way of retrieving a uid for the object. This is coming in a future patch. PR-URL: https://github.com/nodejs/node/pull/5756 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
This commit is contained in:
parent
f9938b6141
commit
20337addd6
@ -9,6 +9,7 @@
|
||||
#include "v8-profiler.h"
|
||||
|
||||
using v8::Array;
|
||||
using v8::Boolean;
|
||||
using v8::Context;
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
@ -231,7 +232,9 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
||||
Local<Value> ret = cb->Call(context, argc, argv);
|
||||
|
||||
if (ran_init_callback() && !post_fn.IsEmpty()) {
|
||||
if (post_fn->Call(context, 1, &uid).IsEmpty())
|
||||
Local<Value> did_throw = Boolean::New(env()->isolate(), ret.IsEmpty());
|
||||
Local<Value> vals[] = { uid, did_throw };
|
||||
if (post_fn->Call(context, ARRAY_SIZE(vals), vals).IsEmpty())
|
||||
FatalError("node::AsyncWrap::MakeCallback", "post hook threw");
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1200,12 @@ Local<Value> MakeCallback(Environment* env,
|
||||
Local<Value> ret = callback->Call(recv, argc, argv);
|
||||
|
||||
if (ran_init_callback && !post_fn.IsEmpty()) {
|
||||
if (post_fn->Call(object, 0, nullptr).IsEmpty())
|
||||
Local<Value> did_throw = Boolean::New(env->isolate(), ret.IsEmpty());
|
||||
// Currently there's no way to retrieve an uid from node::MakeCallback().
|
||||
// This needs to be fixed.
|
||||
Local<Value> vals[] =
|
||||
{ Undefined(env->isolate()).As<Value>(), did_throw };
|
||||
if (post_fn->Call(object, ARRAY_SIZE(vals), vals).IsEmpty())
|
||||
FatalError("node::MakeCallback", "post hook threw");
|
||||
}
|
||||
|
||||
|
34
test/parallel/test-async-wrap-post-did-throw.js
Normal file
34
test/parallel/test-async-wrap-post-did-throw.js
Normal file
@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const async_wrap = process.binding('async_wrap');
|
||||
var asyncThrows = 0;
|
||||
var uncaughtExceptionCount = 0;
|
||||
|
||||
process.on('uncaughtException', (e) => {
|
||||
assert.equal(e.message, 'oh noes!', 'error messages do not match');
|
||||
});
|
||||
|
||||
process.on('exit', () => {
|
||||
process.removeAllListeners('uncaughtException');
|
||||
assert.equal(uncaughtExceptionCount, 1);
|
||||
assert.equal(uncaughtExceptionCount, asyncThrows);
|
||||
});
|
||||
|
||||
function init() { }
|
||||
function post(id, threw) {
|
||||
if (threw)
|
||||
uncaughtExceptionCount++;
|
||||
}
|
||||
|
||||
async_wrap.setupHooks({ init, post });
|
||||
async_wrap.enable();
|
||||
|
||||
// Timers still aren't supported, so use crypto API.
|
||||
// It's also important that the callback not happen in a nextTick, like many
|
||||
// error events in core.
|
||||
require('crypto').randomBytes(0, () => {
|
||||
asyncThrows++;
|
||||
throw new Error('oh noes!');
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user