Skip to content

Commit

Permalink
n-api: provide node::FatalError() when internals are absent
Browse files Browse the repository at this point in the history
src/node_api.cc must build both as a part of node and as an addon
against an older version of node, so that it may be possible to make
N-API available on older, already-published versions of node. Thus,
it must not make use of node internals such as node::FatalError().

Yet N-API must also exit with a fatal error in the absence of a
napi_env pointer. To that end, node::FatalError() is implemented if
internals are unavailable by copying PrintErrorString() from node.cc,
simplifying it to accept only a location and an error message, and
augmenting it with fflush() and platform-ifdefed abort(), the latter
two of which are also copied from node.cc.

Re nodejs#232
Re https://github.com/nodejs/node-api
  • Loading branch information
Gabriel Schulhof committed Apr 17, 2017
1 parent ade80ee commit 749d89e
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,56 @@
#include "node_api.h"
#include "env-inl.h"

// If we're outside of node we must implement node::FatalError() ourselves
#if not defined(NODE_WANT_INTERNALS) || !NODE_WANT_INTERNALS

// Copied and simplified from node.cc
namespace node {

void FatalError(const char* location, const char *error) {
const char *format = "FATAL ERROR: %s %s\n";
#ifdef _WIN32
HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);

// Check if stderr is something other than a tty/console
if (stderr_handle == INVALID_HANDLE_VALUE ||
stderr_handle == nullptr ||
uv_guess_handle(_fileno(stderr)) != UV_TTY) {
fprintf(stderr, format, location, error);
return;
}

// Fill in any placeholders
int n = _scprintf(format, location, error);
std::vector<char> out(n + 1);
sprintf(out.data(), format, location, error);

// Get required wide buffer size
n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);

std::vector<wchar_t> wbuf(n);
MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);

// Don't include the null character in the output
CHECK_GT(n, 0);
WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
#else
fprintf(stderr, format, location, error);
#endif

fflush(stderr);

// Windows 8+ does not like abort() in Release mode
#ifdef _WIN32
raise(SIGABRT);
#else
abort();
#endif
}

} // namespace node
#endif // internals unavailable or unwanted

static
napi_status napi_set_last_error(napi_env env, napi_status error_code,
uint32_t engine_error_code = 0,
Expand Down

0 comments on commit 749d89e

Please sign in to comment.