Skip to content

N-API: pass error from execute callback in napi_create_async_work to main loop #20964

Description

@mcheshkov
  • Version: v8.4.0
  • Platform: Linux 4.13.0-43-generic Improve repo description #48~16.04.1-Ubuntu SMP Thu May 17 12:56:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem: N-API

I can't find a way to pass error from simple async operation back to main loop.
Tests for async calls napi_throw_type_error straight from execute callback, which should run in thread pool. But napi_throw_type_error does not synchronize access to VM, which, AFAIK, is not allowed, by v8 at least.

void Execute(napi_env env, void* data) {
#if defined _WIN32
Sleep(1000);
#else
sleep(1);
#endif
carrier* c = static_cast<carrier*>(data);
if (c != &the_carrier) {
napi_throw_type_error(env, nullptr, "Wrong data parameter to Execute.");
return;
}
c->_output = c->_input * 2;
}

What is correct way to pass error back? I can make my own variant using data pointer, but something like Nan::AsyncWorker::SetErrorMessage would be nice.
Availability of napi_env in napi_async_execute_callback make things more confusing - it makes me think that I can call any N-API function.

Activity

  1. mhdawson commented on May 25, 2018

    @mhdawson
    Member

    I'd need more context to understand which, but I'm guessing you want either

  2. mcheshkov commented on May 28, 2018

    @mcheshkov
    Author

    #17887 is great, subscribing.

    I have two concerns. Both are about "Simple Asynchronous Operations" as in documentation, running single function in threadpool, parallel to JS thread.

    With NAN one could write something like that

    class Worker : public Nan::AsyncWorker {
     public:
      void Execute () {
        if (true /*error happened*/) { SetErrorMessage("Something bad happened"); }
      }
    };
    

    SetErrorMessage will save message in worker instance field, then libuv will call in JS thread AsyncExecuteComplete -> WorkComplete and it will call either HandleOKCallback or HandleErrorCallback, depending on saved message.

    With N-API you have to do this by hand - define structure for worker context with error message, pass it as data pointer, save message there, handle it in complete callback. It is more flexible, but, still, extra work for (as I see it) default case of running async operation.

    napi_async_execute_callback executes in thread from thread pool.
    One mustn't access VM from other threads, at least in v8.
    But napi_async_execute_callback receives napi_env as argument, and make me think I can use it to create new JS values, call functions or throw exceptions.

  3. jasnell commented on Jun 19, 2020

    @jasnell
    Member

    I believe this has been resolved. Closing. Can reopen if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions