Skip to content

Commit

Permalink
async_wrap: allow some hooks to be optional
Browse files Browse the repository at this point in the history
Only enforce that the init callback is passed to setupHooks(). The
remaining hooks can be optionally passed.

Throw if async_wrap.enable() runs before setting the init callback or if
setupHooks() is called while async wrap is enabled.

Add test to verify calls throw appropriately.

PR-URL: #3461
Reviewed-By: Fedor Indutny <fedor@indutny.com>
  • Loading branch information
trevnorris authored and rvagg committed Nov 7, 2015
1 parent d64a56c commit 5d34c81
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/async-wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ RetainedObjectInfo* WrapperInfo(uint16_t class_id, Local<Value> wrapper) {

static void EnableHooksJS(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Local<Function> init_fn = env->async_hooks_init_function();
if (init_fn.IsEmpty() || !init_fn->IsFunction())
return env->ThrowTypeError("init callback is not assigned to a function");
env->async_hooks()->set_enable_callbacks(1);
}

Expand All @@ -116,13 +119,18 @@ static void DisableHooksJS(const FunctionCallbackInfo<Value>& args) {
static void SetupHooks(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

CHECK(args[0]->IsFunction());
CHECK(args[1]->IsFunction());
CHECK(args[2]->IsFunction());
if (env->async_hooks()->callbacks_enabled())
return env->ThrowError("hooks should not be set while also enabled");

if (!args[0]->IsFunction())
return env->ThrowTypeError("init callback must be a function");

env->set_async_hooks_init_function(args[0].As<Function>());
env->set_async_hooks_pre_function(args[1].As<Function>());
env->set_async_hooks_post_function(args[2].As<Function>());

if (args[1]->IsFunction())
env->set_async_hooks_pre_function(args[1].As<Function>());
if (args[2]->IsFunction())
env->set_async_hooks_post_function(args[2].As<Function>());
}


Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-async-wrap-throw-no-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const async_wrap = process.binding('async_wrap');


assert.throws(function() {
async_wrap.setupHooks(null);
}, /init callback must be a function/);

assert.throws(function() {
async_wrap.enable();
}, /init callback is not assigned to a function/);

// Should not throw
async_wrap.setupHooks(() => {});
async_wrap.enable();

assert.throws(function() {
async_wrap.setupHooks(() => {});
}, /hooks should not be set while also enabled/);

0 comments on commit 5d34c81

Please sign in to comment.