11cb0ef41Sopenharmony_ci#include <cerrno>
21cb0ef41Sopenharmony_ci#include <cstdarg>
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ci#include "debug_utils-inl.h"
51cb0ef41Sopenharmony_ci#include "node_errors.h"
61cb0ef41Sopenharmony_ci#include "node_external_reference.h"
71cb0ef41Sopenharmony_ci#include "node_internals.h"
81cb0ef41Sopenharmony_ci#include "node_process-inl.h"
91cb0ef41Sopenharmony_ci#include "node_report.h"
101cb0ef41Sopenharmony_ci#include "node_v8_platform-inl.h"
111cb0ef41Sopenharmony_ci#include "util-inl.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace node {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciusing errors::TryCatchScope;
161cb0ef41Sopenharmony_ciusing v8::Boolean;
171cb0ef41Sopenharmony_ciusing v8::Context;
181cb0ef41Sopenharmony_ciusing v8::Exception;
191cb0ef41Sopenharmony_ciusing v8::Function;
201cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
211cb0ef41Sopenharmony_ciusing v8::HandleScope;
221cb0ef41Sopenharmony_ciusing v8::Int32;
231cb0ef41Sopenharmony_ciusing v8::Isolate;
241cb0ef41Sopenharmony_ciusing v8::Just;
251cb0ef41Sopenharmony_ciusing v8::Local;
261cb0ef41Sopenharmony_ciusing v8::Maybe;
271cb0ef41Sopenharmony_ciusing v8::MaybeLocal;
281cb0ef41Sopenharmony_ciusing v8::Message;
291cb0ef41Sopenharmony_ciusing v8::Object;
301cb0ef41Sopenharmony_ciusing v8::ScriptOrigin;
311cb0ef41Sopenharmony_ciusing v8::StackFrame;
321cb0ef41Sopenharmony_ciusing v8::StackTrace;
331cb0ef41Sopenharmony_ciusing v8::String;
341cb0ef41Sopenharmony_ciusing v8::Undefined;
351cb0ef41Sopenharmony_ciusing v8::Value;
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cibool IsExceptionDecorated(Environment* env, Local<Value> er) {
381cb0ef41Sopenharmony_ci  if (!er.IsEmpty() && er->IsObject()) {
391cb0ef41Sopenharmony_ci    Local<Object> err_obj = er.As<Object>();
401cb0ef41Sopenharmony_ci    auto maybe_value =
411cb0ef41Sopenharmony_ci        err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
421cb0ef41Sopenharmony_ci    Local<Value> decorated;
431cb0ef41Sopenharmony_ci    return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
441cb0ef41Sopenharmony_ci  }
451cb0ef41Sopenharmony_ci  return false;
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cinamespace per_process {
491cb0ef41Sopenharmony_cistatic Mutex tty_mutex;
501cb0ef41Sopenharmony_ci}  // namespace per_process
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_cistatic std::string GetSourceMapErrorSource(Isolate* isolate,
531cb0ef41Sopenharmony_ci                                           Local<Context> context,
541cb0ef41Sopenharmony_ci                                           Local<Message> message,
551cb0ef41Sopenharmony_ci                                           bool* added_exception_line) {
561cb0ef41Sopenharmony_ci  v8::TryCatch try_catch(isolate);
571cb0ef41Sopenharmony_ci  HandleScope handle_scope(isolate);
581cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  // The ScriptResourceName of the message may be different from the one we use
611cb0ef41Sopenharmony_ci  // to compile the script. V8 replaces it when it detects magic comments in
621cb0ef41Sopenharmony_ci  // the source texts.
631cb0ef41Sopenharmony_ci  Local<Value> script_resource_name = message->GetScriptResourceName();
641cb0ef41Sopenharmony_ci  int linenum = message->GetLineNumber(context).FromJust();
651cb0ef41Sopenharmony_ci  int columnum = message->GetStartColumn(context).FromJust();
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  Local<Value> argv[] = {script_resource_name,
681cb0ef41Sopenharmony_ci                         v8::Int32::New(isolate, linenum),
691cb0ef41Sopenharmony_ci                         v8::Int32::New(isolate, columnum)};
701cb0ef41Sopenharmony_ci  MaybeLocal<Value> maybe_ret = env->get_source_map_error_source()->Call(
711cb0ef41Sopenharmony_ci      context, Undefined(isolate), arraysize(argv), argv);
721cb0ef41Sopenharmony_ci  Local<Value> ret;
731cb0ef41Sopenharmony_ci  if (!maybe_ret.ToLocal(&ret)) {
741cb0ef41Sopenharmony_ci    // Ignore the caught exceptions.
751cb0ef41Sopenharmony_ci    DCHECK(try_catch.HasCaught());
761cb0ef41Sopenharmony_ci    return std::string();
771cb0ef41Sopenharmony_ci  }
781cb0ef41Sopenharmony_ci  if (!ret->IsString()) {
791cb0ef41Sopenharmony_ci    return std::string();
801cb0ef41Sopenharmony_ci  }
811cb0ef41Sopenharmony_ci  *added_exception_line = true;
821cb0ef41Sopenharmony_ci  node::Utf8Value error_source_utf8(isolate, ret.As<String>());
831cb0ef41Sopenharmony_ci  return *error_source_utf8;
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cistatic std::string GetErrorSource(Isolate* isolate,
871cb0ef41Sopenharmony_ci                                  Local<Context> context,
881cb0ef41Sopenharmony_ci                                  Local<Message> message,
891cb0ef41Sopenharmony_ci                                  bool* added_exception_line) {
901cb0ef41Sopenharmony_ci  MaybeLocal<String> source_line_maybe = message->GetSourceLine(context);
911cb0ef41Sopenharmony_ci  node::Utf8Value encoded_source(isolate, source_line_maybe.ToLocalChecked());
921cb0ef41Sopenharmony_ci  std::string sourceline(*encoded_source, encoded_source.length());
931cb0ef41Sopenharmony_ci  *added_exception_line = false;
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  if (sourceline.find("node-do-not-add-exception-line") != std::string::npos) {
961cb0ef41Sopenharmony_ci    return sourceline;
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  // If source maps have been enabled, the exception line will instead be
1001cb0ef41Sopenharmony_ci  // added in the JavaScript context:
1011cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(isolate);
1021cb0ef41Sopenharmony_ci  const bool has_source_map_url =
1031cb0ef41Sopenharmony_ci      !message->GetScriptOrigin().SourceMapUrl().IsEmpty() &&
1041cb0ef41Sopenharmony_ci      !message->GetScriptOrigin().SourceMapUrl()->IsUndefined();
1051cb0ef41Sopenharmony_ci  if (has_source_map_url && env != nullptr && env->source_maps_enabled()) {
1061cb0ef41Sopenharmony_ci    std::string source = GetSourceMapErrorSource(
1071cb0ef41Sopenharmony_ci        isolate, context, message, added_exception_line);
1081cb0ef41Sopenharmony_ci    if (*added_exception_line) {
1091cb0ef41Sopenharmony_ci      return source;
1101cb0ef41Sopenharmony_ci    }
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  // Because of how node modules work, all scripts are wrapped with a
1141cb0ef41Sopenharmony_ci  // "function (module, exports, __filename, ...) {"
1151cb0ef41Sopenharmony_ci  // to provide script local variables.
1161cb0ef41Sopenharmony_ci  //
1171cb0ef41Sopenharmony_ci  // When reporting errors on the first line of a script, this wrapper
1181cb0ef41Sopenharmony_ci  // function is leaked to the user. There used to be a hack here to
1191cb0ef41Sopenharmony_ci  // truncate off the first 62 characters, but it caused numerous other
1201cb0ef41Sopenharmony_ci  // problems when vm.runIn*Context() methods were used for non-module
1211cb0ef41Sopenharmony_ci  // code.
1221cb0ef41Sopenharmony_ci  //
1231cb0ef41Sopenharmony_ci  // If we ever decide to re-instate such a hack, the following steps
1241cb0ef41Sopenharmony_ci  // must be taken:
1251cb0ef41Sopenharmony_ci  //
1261cb0ef41Sopenharmony_ci  // 1. Pass a flag around to say "this code was wrapped"
1271cb0ef41Sopenharmony_ci  // 2. Update the stack frame output so that it is also correct.
1281cb0ef41Sopenharmony_ci  //
1291cb0ef41Sopenharmony_ci  // It would probably be simpler to add a line rather than add some
1301cb0ef41Sopenharmony_ci  // number of characters to the first line, since V8 truncates the
1311cb0ef41Sopenharmony_ci  // sourceline to 78 characters, and we end up not providing very much
1321cb0ef41Sopenharmony_ci  // useful debugging info to the user if we remove 62 characters.
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // Print (filename):(line number): (message).
1351cb0ef41Sopenharmony_ci  ScriptOrigin origin = message->GetScriptOrigin();
1361cb0ef41Sopenharmony_ci  node::Utf8Value filename(isolate, message->GetScriptResourceName());
1371cb0ef41Sopenharmony_ci  const char* filename_string = *filename;
1381cb0ef41Sopenharmony_ci  int linenum = message->GetLineNumber(context).FromJust();
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  int script_start = (linenum - origin.LineOffset()) == 1
1411cb0ef41Sopenharmony_ci                         ? origin.ColumnOffset()
1421cb0ef41Sopenharmony_ci                         : 0;
1431cb0ef41Sopenharmony_ci  int start = message->GetStartColumn(context).FromMaybe(0);
1441cb0ef41Sopenharmony_ci  int end = message->GetEndColumn(context).FromMaybe(0);
1451cb0ef41Sopenharmony_ci  if (start >= script_start) {
1461cb0ef41Sopenharmony_ci    CHECK_GE(end, start);
1471cb0ef41Sopenharmony_ci    start -= script_start;
1481cb0ef41Sopenharmony_ci    end -= script_start;
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  std::string buf = SPrintF("%s:%i\n%s\n",
1521cb0ef41Sopenharmony_ci                            filename_string,
1531cb0ef41Sopenharmony_ci                            linenum,
1541cb0ef41Sopenharmony_ci                            sourceline.c_str());
1551cb0ef41Sopenharmony_ci  CHECK_GT(buf.size(), 0);
1561cb0ef41Sopenharmony_ci  *added_exception_line = true;
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  if (start > end ||
1591cb0ef41Sopenharmony_ci      start < 0 ||
1601cb0ef41Sopenharmony_ci      static_cast<size_t>(end) > sourceline.size()) {
1611cb0ef41Sopenharmony_ci    return buf;
1621cb0ef41Sopenharmony_ci  }
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci  constexpr int kUnderlineBufsize = 1020;
1651cb0ef41Sopenharmony_ci  char underline_buf[kUnderlineBufsize + 4];
1661cb0ef41Sopenharmony_ci  int off = 0;
1671cb0ef41Sopenharmony_ci  // Print wavy underline (GetUnderline is deprecated).
1681cb0ef41Sopenharmony_ci  for (int i = 0; i < start; i++) {
1691cb0ef41Sopenharmony_ci    if (sourceline[i] == '\0' || off >= kUnderlineBufsize) {
1701cb0ef41Sopenharmony_ci      break;
1711cb0ef41Sopenharmony_ci    }
1721cb0ef41Sopenharmony_ci    CHECK_LT(off, kUnderlineBufsize);
1731cb0ef41Sopenharmony_ci    underline_buf[off++] = (sourceline[i] == '\t') ? '\t' : ' ';
1741cb0ef41Sopenharmony_ci  }
1751cb0ef41Sopenharmony_ci  for (int i = start; i < end; i++) {
1761cb0ef41Sopenharmony_ci    if (sourceline[i] == '\0' || off >= kUnderlineBufsize) {
1771cb0ef41Sopenharmony_ci      break;
1781cb0ef41Sopenharmony_ci    }
1791cb0ef41Sopenharmony_ci    CHECK_LT(off, kUnderlineBufsize);
1801cb0ef41Sopenharmony_ci    underline_buf[off++] = '^';
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci  CHECK_LE(off, kUnderlineBufsize);
1831cb0ef41Sopenharmony_ci  underline_buf[off++] = '\n';
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  return buf + std::string(underline_buf, off);
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_cistatic std::string FormatStackTrace(Isolate* isolate, Local<StackTrace> stack) {
1891cb0ef41Sopenharmony_ci  std::string result;
1901cb0ef41Sopenharmony_ci  for (int i = 0; i < stack->GetFrameCount(); i++) {
1911cb0ef41Sopenharmony_ci    Local<StackFrame> stack_frame = stack->GetFrame(isolate, i);
1921cb0ef41Sopenharmony_ci    node::Utf8Value fn_name_s(isolate, stack_frame->GetFunctionName());
1931cb0ef41Sopenharmony_ci    node::Utf8Value script_name(isolate, stack_frame->GetScriptName());
1941cb0ef41Sopenharmony_ci    const int line_number = stack_frame->GetLineNumber();
1951cb0ef41Sopenharmony_ci    const int column = stack_frame->GetColumn();
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci    if (stack_frame->IsEval()) {
1981cb0ef41Sopenharmony_ci      if (stack_frame->GetScriptId() == Message::kNoScriptIdInfo) {
1991cb0ef41Sopenharmony_ci        result += SPrintF("    at [eval]:%i:%i\n", line_number, column);
2001cb0ef41Sopenharmony_ci      } else {
2011cb0ef41Sopenharmony_ci        std::vector<char> buf(script_name.length() + 64);
2021cb0ef41Sopenharmony_ci        snprintf(buf.data(),
2031cb0ef41Sopenharmony_ci                 buf.size(),
2041cb0ef41Sopenharmony_ci                 "    at [eval] (%s:%i:%i)\n",
2051cb0ef41Sopenharmony_ci                 *script_name,
2061cb0ef41Sopenharmony_ci                 line_number,
2071cb0ef41Sopenharmony_ci                 column);
2081cb0ef41Sopenharmony_ci        result += std::string(buf.data());
2091cb0ef41Sopenharmony_ci      }
2101cb0ef41Sopenharmony_ci      break;
2111cb0ef41Sopenharmony_ci    }
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci    if (fn_name_s.length() == 0) {
2141cb0ef41Sopenharmony_ci      std::vector<char> buf(script_name.length() + 64);
2151cb0ef41Sopenharmony_ci      snprintf(buf.data(),
2161cb0ef41Sopenharmony_ci               buf.size(),
2171cb0ef41Sopenharmony_ci               "    at %s:%i:%i\n",
2181cb0ef41Sopenharmony_ci               *script_name,
2191cb0ef41Sopenharmony_ci               line_number,
2201cb0ef41Sopenharmony_ci               column);
2211cb0ef41Sopenharmony_ci      result += std::string(buf.data());
2221cb0ef41Sopenharmony_ci    } else {
2231cb0ef41Sopenharmony_ci      std::vector<char> buf(fn_name_s.length() + script_name.length() + 64);
2241cb0ef41Sopenharmony_ci      snprintf(buf.data(),
2251cb0ef41Sopenharmony_ci               buf.size(),
2261cb0ef41Sopenharmony_ci               "    at %s (%s:%i:%i)\n",
2271cb0ef41Sopenharmony_ci               *fn_name_s,
2281cb0ef41Sopenharmony_ci               *script_name,
2291cb0ef41Sopenharmony_ci               line_number,
2301cb0ef41Sopenharmony_ci               column);
2311cb0ef41Sopenharmony_ci      result += std::string(buf.data());
2321cb0ef41Sopenharmony_ci    }
2331cb0ef41Sopenharmony_ci  }
2341cb0ef41Sopenharmony_ci  return result;
2351cb0ef41Sopenharmony_ci}
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_cistatic void PrintToStderrAndFlush(const std::string& str) {
2381cb0ef41Sopenharmony_ci  FPrintF(stderr, "%s\n", str);
2391cb0ef41Sopenharmony_ci  fflush(stderr);
2401cb0ef41Sopenharmony_ci}
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_civoid PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
2431cb0ef41Sopenharmony_ci  PrintToStderrAndFlush(FormatStackTrace(isolate, stack));
2441cb0ef41Sopenharmony_ci}
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_cistd::string FormatCaughtException(Isolate* isolate,
2471cb0ef41Sopenharmony_ci                                  Local<Context> context,
2481cb0ef41Sopenharmony_ci                                  Local<Value> err,
2491cb0ef41Sopenharmony_ci                                  Local<Message> message) {
2501cb0ef41Sopenharmony_ci  node::Utf8Value reason(isolate,
2511cb0ef41Sopenharmony_ci                         err->ToDetailString(context)
2521cb0ef41Sopenharmony_ci                             .FromMaybe(Local<String>()));
2531cb0ef41Sopenharmony_ci  bool added_exception_line = false;
2541cb0ef41Sopenharmony_ci  std::string source =
2551cb0ef41Sopenharmony_ci      GetErrorSource(isolate, context, message, &added_exception_line);
2561cb0ef41Sopenharmony_ci  std::string result = source + '\n' + reason.ToString() + '\n';
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  Local<v8::StackTrace> stack = message->GetStackTrace();
2591cb0ef41Sopenharmony_ci  if (!stack.IsEmpty()) result += FormatStackTrace(isolate, stack);
2601cb0ef41Sopenharmony_ci  return result;
2611cb0ef41Sopenharmony_ci}
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_cistd::string FormatCaughtException(Isolate* isolate,
2641cb0ef41Sopenharmony_ci                                  Local<Context> context,
2651cb0ef41Sopenharmony_ci                                  const v8::TryCatch& try_catch) {
2661cb0ef41Sopenharmony_ci  CHECK(try_catch.HasCaught());
2671cb0ef41Sopenharmony_ci  return FormatCaughtException(
2681cb0ef41Sopenharmony_ci      isolate, context, try_catch.Exception(), try_catch.Message());
2691cb0ef41Sopenharmony_ci}
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_civoid PrintCaughtException(Isolate* isolate,
2721cb0ef41Sopenharmony_ci                          Local<Context> context,
2731cb0ef41Sopenharmony_ci                          const v8::TryCatch& try_catch) {
2741cb0ef41Sopenharmony_ci  PrintToStderrAndFlush(FormatCaughtException(isolate, context, try_catch));
2751cb0ef41Sopenharmony_ci}
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_civoid AppendExceptionLine(Environment* env,
2781cb0ef41Sopenharmony_ci                         Local<Value> er,
2791cb0ef41Sopenharmony_ci                         Local<Message> message,
2801cb0ef41Sopenharmony_ci                         enum ErrorHandlingMode mode) {
2811cb0ef41Sopenharmony_ci  if (message.IsEmpty()) return;
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  HandleScope scope(env->isolate());
2841cb0ef41Sopenharmony_ci  Local<Object> err_obj;
2851cb0ef41Sopenharmony_ci  if (!er.IsEmpty() && er->IsObject()) {
2861cb0ef41Sopenharmony_ci    err_obj = er.As<Object>();
2871cb0ef41Sopenharmony_ci    // If arrow_message is already set, skip.
2881cb0ef41Sopenharmony_ci    auto maybe_value = err_obj->GetPrivate(env->context(),
2891cb0ef41Sopenharmony_ci                                          env->arrow_message_private_symbol());
2901cb0ef41Sopenharmony_ci    Local<Value> lvalue;
2911cb0ef41Sopenharmony_ci    if (!maybe_value.ToLocal(&lvalue) || lvalue->IsString())
2921cb0ef41Sopenharmony_ci      return;
2931cb0ef41Sopenharmony_ci  }
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  bool added_exception_line = false;
2961cb0ef41Sopenharmony_ci  std::string source = GetErrorSource(
2971cb0ef41Sopenharmony_ci      env->isolate(), env->context(), message, &added_exception_line);
2981cb0ef41Sopenharmony_ci  if (!added_exception_line) {
2991cb0ef41Sopenharmony_ci    return;
3001cb0ef41Sopenharmony_ci  }
3011cb0ef41Sopenharmony_ci  MaybeLocal<Value> arrow_str = ToV8Value(env->context(), source);
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci  const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
3041cb0ef41Sopenharmony_ci  // If allocating arrow_str failed, print it out. There's not much else to do.
3051cb0ef41Sopenharmony_ci  // If it's not an error, but something needs to be printed out because
3061cb0ef41Sopenharmony_ci  // it's a fatal exception, also print it out from here.
3071cb0ef41Sopenharmony_ci  // Otherwise, the arrow property will be attached to the object and handled
3081cb0ef41Sopenharmony_ci  // by the caller.
3091cb0ef41Sopenharmony_ci  if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
3101cb0ef41Sopenharmony_ci    if (env->printed_error()) return;
3111cb0ef41Sopenharmony_ci    Mutex::ScopedLock lock(per_process::tty_mutex);
3121cb0ef41Sopenharmony_ci    env->set_printed_error(true);
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci    ResetStdio();
3151cb0ef41Sopenharmony_ci    FPrintF(stderr, "\n%s", source);
3161cb0ef41Sopenharmony_ci    return;
3171cb0ef41Sopenharmony_ci  }
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci  CHECK(err_obj
3201cb0ef41Sopenharmony_ci            ->SetPrivate(env->context(),
3211cb0ef41Sopenharmony_ci                         env->arrow_message_private_symbol(),
3221cb0ef41Sopenharmony_ci                         arrow_str.ToLocalChecked())
3231cb0ef41Sopenharmony_ci            .FromMaybe(false));
3241cb0ef41Sopenharmony_ci}
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci[[noreturn]] void Abort() {
3271cb0ef41Sopenharmony_ci  DumpBacktrace(stderr);
3281cb0ef41Sopenharmony_ci  fflush(stderr);
3291cb0ef41Sopenharmony_ci  ABORT_NO_BACKTRACE();
3301cb0ef41Sopenharmony_ci}
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci[[noreturn]] void Assert(const AssertionInfo& info) {
3331cb0ef41Sopenharmony_ci  std::string name = GetHumanReadableProcessName();
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  fprintf(stderr,
3361cb0ef41Sopenharmony_ci          "%s: %s:%s%s Assertion `%s' failed.\n",
3371cb0ef41Sopenharmony_ci          name.c_str(),
3381cb0ef41Sopenharmony_ci          info.file_line,
3391cb0ef41Sopenharmony_ci          info.function,
3401cb0ef41Sopenharmony_ci          *info.function ? ":" : "",
3411cb0ef41Sopenharmony_ci          info.message);
3421cb0ef41Sopenharmony_ci  fflush(stderr);
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  Abort();
3451cb0ef41Sopenharmony_ci}
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_cienum class EnhanceFatalException { kEnhance, kDontEnhance };
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci/**
3501cb0ef41Sopenharmony_ci * Report the exception to the inspector, then print it to stderr.
3511cb0ef41Sopenharmony_ci * This should only be used when the Node.js instance is about to exit
3521cb0ef41Sopenharmony_ci * (i.e. this should be followed by a env->Exit() or an Abort()).
3531cb0ef41Sopenharmony_ci *
3541cb0ef41Sopenharmony_ci * Use enhance_stack = EnhanceFatalException::kDontEnhance
3551cb0ef41Sopenharmony_ci * when it's unsafe to call into JavaScript.
3561cb0ef41Sopenharmony_ci */
3571cb0ef41Sopenharmony_cistatic void ReportFatalException(Environment* env,
3581cb0ef41Sopenharmony_ci                                 Local<Value> error,
3591cb0ef41Sopenharmony_ci                                 Local<Message> message,
3601cb0ef41Sopenharmony_ci                                 EnhanceFatalException enhance_stack) {
3611cb0ef41Sopenharmony_ci  if (!env->can_call_into_js())
3621cb0ef41Sopenharmony_ci    enhance_stack = EnhanceFatalException::kDontEnhance;
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  Isolate* isolate = env->isolate();
3651cb0ef41Sopenharmony_ci  CHECK(!error.IsEmpty());
3661cb0ef41Sopenharmony_ci  CHECK(!message.IsEmpty());
3671cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  AppendExceptionLine(env, error, message, FATAL_ERROR);
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  auto report_to_inspector = [&]() {
3721cb0ef41Sopenharmony_ci#if HAVE_INSPECTOR
3731cb0ef41Sopenharmony_ci    env->inspector_agent()->ReportUncaughtException(error, message);
3741cb0ef41Sopenharmony_ci#endif
3751cb0ef41Sopenharmony_ci  };
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci  Local<Value> arrow;
3781cb0ef41Sopenharmony_ci  Local<Value> stack_trace;
3791cb0ef41Sopenharmony_ci  bool decorated = IsExceptionDecorated(env, error);
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci  if (!error->IsObject()) {  // We can only enhance actual errors.
3821cb0ef41Sopenharmony_ci    report_to_inspector();
3831cb0ef41Sopenharmony_ci    stack_trace = Undefined(isolate);
3841cb0ef41Sopenharmony_ci    // If error is not an object, AppendExceptionLine() has already print the
3851cb0ef41Sopenharmony_ci    // source line and the arrow to stderr.
3861cb0ef41Sopenharmony_ci    // TODO(joyeecheung): move that side effect out of AppendExceptionLine().
3871cb0ef41Sopenharmony_ci    // It is done just to preserve the source line as soon as possible.
3881cb0ef41Sopenharmony_ci  } else {
3891cb0ef41Sopenharmony_ci    Local<Object> err_obj = error.As<Object>();
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci    auto enhance_with = [&](Local<Function> enhancer) {
3921cb0ef41Sopenharmony_ci      Local<Value> enhanced;
3931cb0ef41Sopenharmony_ci      Local<Value> argv[] = {err_obj};
3941cb0ef41Sopenharmony_ci      if (!enhancer.IsEmpty() &&
3951cb0ef41Sopenharmony_ci          enhancer
3961cb0ef41Sopenharmony_ci              ->Call(env->context(), Undefined(isolate), arraysize(argv), argv)
3971cb0ef41Sopenharmony_ci              .ToLocal(&enhanced)) {
3981cb0ef41Sopenharmony_ci        stack_trace = enhanced;
3991cb0ef41Sopenharmony_ci      }
4001cb0ef41Sopenharmony_ci    };
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci    switch (enhance_stack) {
4031cb0ef41Sopenharmony_ci      case EnhanceFatalException::kEnhance: {
4041cb0ef41Sopenharmony_ci        enhance_with(env->enhance_fatal_stack_before_inspector());
4051cb0ef41Sopenharmony_ci        report_to_inspector();
4061cb0ef41Sopenharmony_ci        enhance_with(env->enhance_fatal_stack_after_inspector());
4071cb0ef41Sopenharmony_ci        break;
4081cb0ef41Sopenharmony_ci      }
4091cb0ef41Sopenharmony_ci      case EnhanceFatalException::kDontEnhance: {
4101cb0ef41Sopenharmony_ci        USE(err_obj->Get(env->context(), env->stack_string())
4111cb0ef41Sopenharmony_ci                .ToLocal(&stack_trace));
4121cb0ef41Sopenharmony_ci        report_to_inspector();
4131cb0ef41Sopenharmony_ci        break;
4141cb0ef41Sopenharmony_ci      }
4151cb0ef41Sopenharmony_ci      default:
4161cb0ef41Sopenharmony_ci        UNREACHABLE();
4171cb0ef41Sopenharmony_ci    }
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ci    arrow =
4201cb0ef41Sopenharmony_ci        err_obj->GetPrivate(env->context(), env->arrow_message_private_symbol())
4211cb0ef41Sopenharmony_ci            .ToLocalChecked();
4221cb0ef41Sopenharmony_ci  }
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci  node::Utf8Value trace(env->isolate(), stack_trace);
4251cb0ef41Sopenharmony_ci  std::string report_message = "Exception";
4261cb0ef41Sopenharmony_ci
4271cb0ef41Sopenharmony_ci  // range errors have a trace member set to undefined
4281cb0ef41Sopenharmony_ci  if (trace.length() > 0 && !stack_trace->IsUndefined()) {
4291cb0ef41Sopenharmony_ci    if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
4301cb0ef41Sopenharmony_ci      FPrintF(stderr, "%s\n", trace);
4311cb0ef41Sopenharmony_ci    } else {
4321cb0ef41Sopenharmony_ci      node::Utf8Value arrow_string(env->isolate(), arrow);
4331cb0ef41Sopenharmony_ci      FPrintF(stderr, "%s\n%s\n", arrow_string, trace);
4341cb0ef41Sopenharmony_ci    }
4351cb0ef41Sopenharmony_ci  } else {
4361cb0ef41Sopenharmony_ci    // this really only happens for RangeErrors, since they're the only
4371cb0ef41Sopenharmony_ci    // kind that won't have all this info in the trace, or when non-Error
4381cb0ef41Sopenharmony_ci    // objects are thrown manually.
4391cb0ef41Sopenharmony_ci    MaybeLocal<Value> message;
4401cb0ef41Sopenharmony_ci    MaybeLocal<Value> name;
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci    if (error->IsObject()) {
4431cb0ef41Sopenharmony_ci      Local<Object> err_obj = error.As<Object>();
4441cb0ef41Sopenharmony_ci      message = err_obj->Get(env->context(), env->message_string());
4451cb0ef41Sopenharmony_ci      name = err_obj->Get(env->context(), env->name_string());
4461cb0ef41Sopenharmony_ci    }
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ci    if (message.IsEmpty() || message.ToLocalChecked()->IsUndefined() ||
4491cb0ef41Sopenharmony_ci        name.IsEmpty() || name.ToLocalChecked()->IsUndefined()) {
4501cb0ef41Sopenharmony_ci      // Not an error object. Just print as-is.
4511cb0ef41Sopenharmony_ci      node::Utf8Value message(env->isolate(), error);
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci      FPrintF(
4541cb0ef41Sopenharmony_ci          stderr,
4551cb0ef41Sopenharmony_ci          "%s\n",
4561cb0ef41Sopenharmony_ci          *message ? message.ToStringView() : "<toString() threw exception>");
4571cb0ef41Sopenharmony_ci    } else {
4581cb0ef41Sopenharmony_ci      node::Utf8Value name_string(env->isolate(), name.ToLocalChecked());
4591cb0ef41Sopenharmony_ci      node::Utf8Value message_string(env->isolate(), message.ToLocalChecked());
4601cb0ef41Sopenharmony_ci      // Update the report message if it is an object has message property.
4611cb0ef41Sopenharmony_ci      report_message = message_string.ToString();
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci      if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
4641cb0ef41Sopenharmony_ci        FPrintF(stderr, "%s: %s\n", name_string, message_string);
4651cb0ef41Sopenharmony_ci      } else {
4661cb0ef41Sopenharmony_ci        node::Utf8Value arrow_string(env->isolate(), arrow);
4671cb0ef41Sopenharmony_ci        FPrintF(stderr,
4681cb0ef41Sopenharmony_ci            "%s\n%s: %s\n", arrow_string, name_string, message_string);
4691cb0ef41Sopenharmony_ci      }
4701cb0ef41Sopenharmony_ci    }
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci    if (!env->options()->trace_uncaught) {
4731cb0ef41Sopenharmony_ci      std::string argv0;
4741cb0ef41Sopenharmony_ci      if (!env->argv().empty()) argv0 = env->argv()[0];
4751cb0ef41Sopenharmony_ci      if (argv0.empty()) argv0 = "node";
4761cb0ef41Sopenharmony_ci      FPrintF(stderr,
4771cb0ef41Sopenharmony_ci              "(Use `%s --trace-uncaught ...` to show where the exception "
4781cb0ef41Sopenharmony_ci              "was thrown)\n",
4791cb0ef41Sopenharmony_ci              fs::Basename(argv0, ".exe"));
4801cb0ef41Sopenharmony_ci    }
4811cb0ef41Sopenharmony_ci  }
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci  if (env->isolate_data()->options()->report_uncaught_exception) {
4841cb0ef41Sopenharmony_ci    TriggerNodeReport(env, report_message.c_str(), "Exception", "", error);
4851cb0ef41Sopenharmony_ci  }
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci  if (env->options()->trace_uncaught) {
4881cb0ef41Sopenharmony_ci    Local<StackTrace> trace = message->GetStackTrace();
4891cb0ef41Sopenharmony_ci    if (!trace.IsEmpty()) {
4901cb0ef41Sopenharmony_ci      FPrintF(stderr, "Thrown at:\n");
4911cb0ef41Sopenharmony_ci      PrintStackTrace(env->isolate(), trace);
4921cb0ef41Sopenharmony_ci    }
4931cb0ef41Sopenharmony_ci  }
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci  if (env->options()->extra_info_on_fatal_exception) {
4961cb0ef41Sopenharmony_ci    FPrintF(stderr, "\nNode.js %s\n", NODE_VERSION);
4971cb0ef41Sopenharmony_ci  }
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ci  fflush(stderr);
5001cb0ef41Sopenharmony_ci}
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci[[noreturn]] void OnFatalError(const char* location, const char* message) {
5031cb0ef41Sopenharmony_ci  if (location) {
5041cb0ef41Sopenharmony_ci    FPrintF(stderr, "FATAL ERROR: %s %s\n", location, message);
5051cb0ef41Sopenharmony_ci  } else {
5061cb0ef41Sopenharmony_ci    FPrintF(stderr, "FATAL ERROR: %s\n", message);
5071cb0ef41Sopenharmony_ci  }
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  Isolate* isolate = Isolate::TryGetCurrent();
5101cb0ef41Sopenharmony_ci  bool report_on_fatalerror;
5111cb0ef41Sopenharmony_ci  {
5121cb0ef41Sopenharmony_ci    Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
5131cb0ef41Sopenharmony_ci    report_on_fatalerror = per_process::cli_options->report_on_fatalerror;
5141cb0ef41Sopenharmony_ci  }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  if (report_on_fatalerror) {
5171cb0ef41Sopenharmony_ci    TriggerNodeReport(isolate, message, "FatalError", "", Local<Object>());
5181cb0ef41Sopenharmony_ci  }
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  fflush(stderr);
5211cb0ef41Sopenharmony_ci  ABORT();
5221cb0ef41Sopenharmony_ci}
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci[[noreturn]] void OOMErrorHandler(const char* location, const v8::OOMDetails& details) {
5251cb0ef41Sopenharmony_ci  const char* message =
5261cb0ef41Sopenharmony_ci      details.is_heap_oom ? "Allocation failed - JavaScript heap out of memory"
5271cb0ef41Sopenharmony_ci                  : "Allocation failed - process out of memory";
5281cb0ef41Sopenharmony_ci  if (location) {
5291cb0ef41Sopenharmony_ci    FPrintF(stderr, "FATAL ERROR: %s %s\n", location, message);
5301cb0ef41Sopenharmony_ci  } else {
5311cb0ef41Sopenharmony_ci    FPrintF(stderr, "FATAL ERROR: %s\n", message);
5321cb0ef41Sopenharmony_ci  }
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  Isolate* isolate = Isolate::TryGetCurrent();
5351cb0ef41Sopenharmony_ci  bool report_on_fatalerror;
5361cb0ef41Sopenharmony_ci  {
5371cb0ef41Sopenharmony_ci    Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
5381cb0ef41Sopenharmony_ci    report_on_fatalerror = per_process::cli_options->report_on_fatalerror;
5391cb0ef41Sopenharmony_ci  }
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  if (report_on_fatalerror) {
5421cb0ef41Sopenharmony_ci    // Trigger report with the isolate. Environment::GetCurrent may return
5431cb0ef41Sopenharmony_ci    // nullptr here:
5441cb0ef41Sopenharmony_ci    // - If the OOM is reported by a young generation space allocation,
5451cb0ef41Sopenharmony_ci    //   Isolate::GetCurrentContext returns an empty handle.
5461cb0ef41Sopenharmony_ci    // - Otherwise, Isolate::GetCurrentContext returns a non-empty handle.
5471cb0ef41Sopenharmony_ci    TriggerNodeReport(isolate, message, "OOMError", "", Local<Object>());
5481cb0ef41Sopenharmony_ci  }
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  fflush(stderr);
5511cb0ef41Sopenharmony_ci  ABORT();
5521cb0ef41Sopenharmony_ci}
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_civ8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings(
5551cb0ef41Sopenharmony_ci    v8::Local<v8::Context> context,
5561cb0ef41Sopenharmony_ci    v8::Local<v8::Value> source,
5571cb0ef41Sopenharmony_ci    bool is_code_like) {
5581cb0ef41Sopenharmony_ci  HandleScope scope(context->GetIsolate());
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
5611cb0ef41Sopenharmony_ci  if (env->source_maps_enabled()) {
5621cb0ef41Sopenharmony_ci    // We do not expect the maybe_cache_generated_source_map to throw any more
5631cb0ef41Sopenharmony_ci    // exceptions. If it does, just ignore it.
5641cb0ef41Sopenharmony_ci    errors::TryCatchScope try_catch(env);
5651cb0ef41Sopenharmony_ci    Local<Function> maybe_cache_source_map =
5661cb0ef41Sopenharmony_ci        env->maybe_cache_generated_source_map();
5671cb0ef41Sopenharmony_ci    Local<Value> argv[1] = {source};
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci    MaybeLocal<Value> maybe_cached = maybe_cache_source_map->Call(
5701cb0ef41Sopenharmony_ci        context, context->Global(), arraysize(argv), argv);
5711cb0ef41Sopenharmony_ci    if (maybe_cached.IsEmpty()) {
5721cb0ef41Sopenharmony_ci      DCHECK(try_catch.HasCaught());
5731cb0ef41Sopenharmony_ci    }
5741cb0ef41Sopenharmony_ci  }
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci  Local<Value> allow_code_gen = context->GetEmbedderData(
5771cb0ef41Sopenharmony_ci      ContextEmbedderIndex::kAllowCodeGenerationFromStrings);
5781cb0ef41Sopenharmony_ci  bool codegen_allowed =
5791cb0ef41Sopenharmony_ci      allow_code_gen->IsUndefined() || allow_code_gen->IsTrue();
5801cb0ef41Sopenharmony_ci  return {
5811cb0ef41Sopenharmony_ci      codegen_allowed,
5821cb0ef41Sopenharmony_ci      {},
5831cb0ef41Sopenharmony_ci  };
5841cb0ef41Sopenharmony_ci}
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_cinamespace errors {
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ciTryCatchScope::~TryCatchScope() {
5891cb0ef41Sopenharmony_ci  if (HasCaught() && !HasTerminated() && mode_ == CatchMode::kFatal) {
5901cb0ef41Sopenharmony_ci    HandleScope scope(env_->isolate());
5911cb0ef41Sopenharmony_ci    Local<v8::Value> exception = Exception();
5921cb0ef41Sopenharmony_ci    Local<v8::Message> message = Message();
5931cb0ef41Sopenharmony_ci    EnhanceFatalException enhance = CanContinue() ?
5941cb0ef41Sopenharmony_ci        EnhanceFatalException::kEnhance : EnhanceFatalException::kDontEnhance;
5951cb0ef41Sopenharmony_ci    if (message.IsEmpty())
5961cb0ef41Sopenharmony_ci      message = Exception::CreateMessage(env_->isolate(), exception);
5971cb0ef41Sopenharmony_ci    ReportFatalException(env_, exception, message, enhance);
5981cb0ef41Sopenharmony_ci    env_->Exit(7);
5991cb0ef41Sopenharmony_ci  }
6001cb0ef41Sopenharmony_ci}
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ciconst char* errno_string(int errorno) {
6031cb0ef41Sopenharmony_ci#define ERRNO_CASE(e)                                                          \
6041cb0ef41Sopenharmony_ci  case e:                                                                      \
6051cb0ef41Sopenharmony_ci    return #e;
6061cb0ef41Sopenharmony_ci  switch (errorno) {
6071cb0ef41Sopenharmony_ci#ifdef EACCES
6081cb0ef41Sopenharmony_ci    ERRNO_CASE(EACCES);
6091cb0ef41Sopenharmony_ci#endif
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci#ifdef EADDRINUSE
6121cb0ef41Sopenharmony_ci    ERRNO_CASE(EADDRINUSE);
6131cb0ef41Sopenharmony_ci#endif
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ci#ifdef EADDRNOTAVAIL
6161cb0ef41Sopenharmony_ci    ERRNO_CASE(EADDRNOTAVAIL);
6171cb0ef41Sopenharmony_ci#endif
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci#ifdef EAFNOSUPPORT
6201cb0ef41Sopenharmony_ci    ERRNO_CASE(EAFNOSUPPORT);
6211cb0ef41Sopenharmony_ci#endif
6221cb0ef41Sopenharmony_ci
6231cb0ef41Sopenharmony_ci#ifdef EAGAIN
6241cb0ef41Sopenharmony_ci    ERRNO_CASE(EAGAIN);
6251cb0ef41Sopenharmony_ci#endif
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci#ifdef EWOULDBLOCK
6281cb0ef41Sopenharmony_ci#if EAGAIN != EWOULDBLOCK
6291cb0ef41Sopenharmony_ci    ERRNO_CASE(EWOULDBLOCK);
6301cb0ef41Sopenharmony_ci#endif
6311cb0ef41Sopenharmony_ci#endif
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci#ifdef EALREADY
6341cb0ef41Sopenharmony_ci    ERRNO_CASE(EALREADY);
6351cb0ef41Sopenharmony_ci#endif
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ci#ifdef EBADF
6381cb0ef41Sopenharmony_ci    ERRNO_CASE(EBADF);
6391cb0ef41Sopenharmony_ci#endif
6401cb0ef41Sopenharmony_ci
6411cb0ef41Sopenharmony_ci#ifdef EBADMSG
6421cb0ef41Sopenharmony_ci    ERRNO_CASE(EBADMSG);
6431cb0ef41Sopenharmony_ci#endif
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ci#ifdef EBUSY
6461cb0ef41Sopenharmony_ci    ERRNO_CASE(EBUSY);
6471cb0ef41Sopenharmony_ci#endif
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci#ifdef ECANCELED
6501cb0ef41Sopenharmony_ci    ERRNO_CASE(ECANCELED);
6511cb0ef41Sopenharmony_ci#endif
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci#ifdef ECHILD
6541cb0ef41Sopenharmony_ci    ERRNO_CASE(ECHILD);
6551cb0ef41Sopenharmony_ci#endif
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_ci#ifdef ECONNABORTED
6581cb0ef41Sopenharmony_ci    ERRNO_CASE(ECONNABORTED);
6591cb0ef41Sopenharmony_ci#endif
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci#ifdef ECONNREFUSED
6621cb0ef41Sopenharmony_ci    ERRNO_CASE(ECONNREFUSED);
6631cb0ef41Sopenharmony_ci#endif
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ci#ifdef ECONNRESET
6661cb0ef41Sopenharmony_ci    ERRNO_CASE(ECONNRESET);
6671cb0ef41Sopenharmony_ci#endif
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci#ifdef EDEADLK
6701cb0ef41Sopenharmony_ci    ERRNO_CASE(EDEADLK);
6711cb0ef41Sopenharmony_ci#endif
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_ci#ifdef EDESTADDRREQ
6741cb0ef41Sopenharmony_ci    ERRNO_CASE(EDESTADDRREQ);
6751cb0ef41Sopenharmony_ci#endif
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci#ifdef EDOM
6781cb0ef41Sopenharmony_ci    ERRNO_CASE(EDOM);
6791cb0ef41Sopenharmony_ci#endif
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci#ifdef EDQUOT
6821cb0ef41Sopenharmony_ci    ERRNO_CASE(EDQUOT);
6831cb0ef41Sopenharmony_ci#endif
6841cb0ef41Sopenharmony_ci
6851cb0ef41Sopenharmony_ci#ifdef EEXIST
6861cb0ef41Sopenharmony_ci    ERRNO_CASE(EEXIST);
6871cb0ef41Sopenharmony_ci#endif
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ci#ifdef EFAULT
6901cb0ef41Sopenharmony_ci    ERRNO_CASE(EFAULT);
6911cb0ef41Sopenharmony_ci#endif
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_ci#ifdef EFBIG
6941cb0ef41Sopenharmony_ci    ERRNO_CASE(EFBIG);
6951cb0ef41Sopenharmony_ci#endif
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci#ifdef EHOSTUNREACH
6981cb0ef41Sopenharmony_ci    ERRNO_CASE(EHOSTUNREACH);
6991cb0ef41Sopenharmony_ci#endif
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci#ifdef EIDRM
7021cb0ef41Sopenharmony_ci    ERRNO_CASE(EIDRM);
7031cb0ef41Sopenharmony_ci#endif
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci#ifdef EILSEQ
7061cb0ef41Sopenharmony_ci    ERRNO_CASE(EILSEQ);
7071cb0ef41Sopenharmony_ci#endif
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci#ifdef EINPROGRESS
7101cb0ef41Sopenharmony_ci    ERRNO_CASE(EINPROGRESS);
7111cb0ef41Sopenharmony_ci#endif
7121cb0ef41Sopenharmony_ci
7131cb0ef41Sopenharmony_ci#ifdef EINTR
7141cb0ef41Sopenharmony_ci    ERRNO_CASE(EINTR);
7151cb0ef41Sopenharmony_ci#endif
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci#ifdef EINVAL
7181cb0ef41Sopenharmony_ci    ERRNO_CASE(EINVAL);
7191cb0ef41Sopenharmony_ci#endif
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci#ifdef EIO
7221cb0ef41Sopenharmony_ci    ERRNO_CASE(EIO);
7231cb0ef41Sopenharmony_ci#endif
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_ci#ifdef EISCONN
7261cb0ef41Sopenharmony_ci    ERRNO_CASE(EISCONN);
7271cb0ef41Sopenharmony_ci#endif
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci#ifdef EISDIR
7301cb0ef41Sopenharmony_ci    ERRNO_CASE(EISDIR);
7311cb0ef41Sopenharmony_ci#endif
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_ci#ifdef ELOOP
7341cb0ef41Sopenharmony_ci    ERRNO_CASE(ELOOP);
7351cb0ef41Sopenharmony_ci#endif
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ci#ifdef EMFILE
7381cb0ef41Sopenharmony_ci    ERRNO_CASE(EMFILE);
7391cb0ef41Sopenharmony_ci#endif
7401cb0ef41Sopenharmony_ci
7411cb0ef41Sopenharmony_ci#ifdef EMLINK
7421cb0ef41Sopenharmony_ci    ERRNO_CASE(EMLINK);
7431cb0ef41Sopenharmony_ci#endif
7441cb0ef41Sopenharmony_ci
7451cb0ef41Sopenharmony_ci#ifdef EMSGSIZE
7461cb0ef41Sopenharmony_ci    ERRNO_CASE(EMSGSIZE);
7471cb0ef41Sopenharmony_ci#endif
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci#ifdef EMULTIHOP
7501cb0ef41Sopenharmony_ci    ERRNO_CASE(EMULTIHOP);
7511cb0ef41Sopenharmony_ci#endif
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ci#ifdef ENAMETOOLONG
7541cb0ef41Sopenharmony_ci    ERRNO_CASE(ENAMETOOLONG);
7551cb0ef41Sopenharmony_ci#endif
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ci#ifdef ENETDOWN
7581cb0ef41Sopenharmony_ci    ERRNO_CASE(ENETDOWN);
7591cb0ef41Sopenharmony_ci#endif
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ci#ifdef ENETRESET
7621cb0ef41Sopenharmony_ci    ERRNO_CASE(ENETRESET);
7631cb0ef41Sopenharmony_ci#endif
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci#ifdef ENETUNREACH
7661cb0ef41Sopenharmony_ci    ERRNO_CASE(ENETUNREACH);
7671cb0ef41Sopenharmony_ci#endif
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci#ifdef ENFILE
7701cb0ef41Sopenharmony_ci    ERRNO_CASE(ENFILE);
7711cb0ef41Sopenharmony_ci#endif
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci#ifdef ENOBUFS
7741cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOBUFS);
7751cb0ef41Sopenharmony_ci#endif
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci#ifdef ENODATA
7781cb0ef41Sopenharmony_ci    ERRNO_CASE(ENODATA);
7791cb0ef41Sopenharmony_ci#endif
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci#ifdef ENODEV
7821cb0ef41Sopenharmony_ci    ERRNO_CASE(ENODEV);
7831cb0ef41Sopenharmony_ci#endif
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci#ifdef ENOENT
7861cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOENT);
7871cb0ef41Sopenharmony_ci#endif
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ci#ifdef ENOEXEC
7901cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOEXEC);
7911cb0ef41Sopenharmony_ci#endif
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ci#ifdef ENOLINK
7941cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOLINK);
7951cb0ef41Sopenharmony_ci#endif
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci#ifdef ENOLCK
7981cb0ef41Sopenharmony_ci#if ENOLINK != ENOLCK
7991cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOLCK);
8001cb0ef41Sopenharmony_ci#endif
8011cb0ef41Sopenharmony_ci#endif
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ci#ifdef ENOMEM
8041cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOMEM);
8051cb0ef41Sopenharmony_ci#endif
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci#ifdef ENOMSG
8081cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOMSG);
8091cb0ef41Sopenharmony_ci#endif
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci#ifdef ENOPROTOOPT
8121cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOPROTOOPT);
8131cb0ef41Sopenharmony_ci#endif
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_ci#ifdef ENOSPC
8161cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOSPC);
8171cb0ef41Sopenharmony_ci#endif
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ci#ifdef ENOSR
8201cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOSR);
8211cb0ef41Sopenharmony_ci#endif
8221cb0ef41Sopenharmony_ci
8231cb0ef41Sopenharmony_ci#ifdef ENOSTR
8241cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOSTR);
8251cb0ef41Sopenharmony_ci#endif
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci#ifdef ENOSYS
8281cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOSYS);
8291cb0ef41Sopenharmony_ci#endif
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci#ifdef ENOTCONN
8321cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTCONN);
8331cb0ef41Sopenharmony_ci#endif
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci#ifdef ENOTDIR
8361cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTDIR);
8371cb0ef41Sopenharmony_ci#endif
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci#ifdef ENOTEMPTY
8401cb0ef41Sopenharmony_ci#if ENOTEMPTY != EEXIST
8411cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTEMPTY);
8421cb0ef41Sopenharmony_ci#endif
8431cb0ef41Sopenharmony_ci#endif
8441cb0ef41Sopenharmony_ci
8451cb0ef41Sopenharmony_ci#ifdef ENOTSOCK
8461cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTSOCK);
8471cb0ef41Sopenharmony_ci#endif
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci#ifdef ENOTSUP
8501cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTSUP);
8511cb0ef41Sopenharmony_ci#else
8521cb0ef41Sopenharmony_ci#ifdef EOPNOTSUPP
8531cb0ef41Sopenharmony_ci    ERRNO_CASE(EOPNOTSUPP);
8541cb0ef41Sopenharmony_ci#endif
8551cb0ef41Sopenharmony_ci#endif
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci#ifdef ENOTTY
8581cb0ef41Sopenharmony_ci    ERRNO_CASE(ENOTTY);
8591cb0ef41Sopenharmony_ci#endif
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_ci#ifdef ENXIO
8621cb0ef41Sopenharmony_ci    ERRNO_CASE(ENXIO);
8631cb0ef41Sopenharmony_ci#endif
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci#ifdef EOVERFLOW
8661cb0ef41Sopenharmony_ci    ERRNO_CASE(EOVERFLOW);
8671cb0ef41Sopenharmony_ci#endif
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_ci#ifdef EPERM
8701cb0ef41Sopenharmony_ci    ERRNO_CASE(EPERM);
8711cb0ef41Sopenharmony_ci#endif
8721cb0ef41Sopenharmony_ci
8731cb0ef41Sopenharmony_ci#ifdef EPIPE
8741cb0ef41Sopenharmony_ci    ERRNO_CASE(EPIPE);
8751cb0ef41Sopenharmony_ci#endif
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci#ifdef EPROTO
8781cb0ef41Sopenharmony_ci    ERRNO_CASE(EPROTO);
8791cb0ef41Sopenharmony_ci#endif
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ci#ifdef EPROTONOSUPPORT
8821cb0ef41Sopenharmony_ci    ERRNO_CASE(EPROTONOSUPPORT);
8831cb0ef41Sopenharmony_ci#endif
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ci#ifdef EPROTOTYPE
8861cb0ef41Sopenharmony_ci    ERRNO_CASE(EPROTOTYPE);
8871cb0ef41Sopenharmony_ci#endif
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci#ifdef ERANGE
8901cb0ef41Sopenharmony_ci    ERRNO_CASE(ERANGE);
8911cb0ef41Sopenharmony_ci#endif
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci#ifdef EROFS
8941cb0ef41Sopenharmony_ci    ERRNO_CASE(EROFS);
8951cb0ef41Sopenharmony_ci#endif
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ci#ifdef ESPIPE
8981cb0ef41Sopenharmony_ci    ERRNO_CASE(ESPIPE);
8991cb0ef41Sopenharmony_ci#endif
9001cb0ef41Sopenharmony_ci
9011cb0ef41Sopenharmony_ci#ifdef ESRCH
9021cb0ef41Sopenharmony_ci    ERRNO_CASE(ESRCH);
9031cb0ef41Sopenharmony_ci#endif
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci#ifdef ESTALE
9061cb0ef41Sopenharmony_ci    ERRNO_CASE(ESTALE);
9071cb0ef41Sopenharmony_ci#endif
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ci#ifdef ETIME
9101cb0ef41Sopenharmony_ci    ERRNO_CASE(ETIME);
9111cb0ef41Sopenharmony_ci#endif
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci#ifdef ETIMEDOUT
9141cb0ef41Sopenharmony_ci    ERRNO_CASE(ETIMEDOUT);
9151cb0ef41Sopenharmony_ci#endif
9161cb0ef41Sopenharmony_ci
9171cb0ef41Sopenharmony_ci#ifdef ETXTBSY
9181cb0ef41Sopenharmony_ci    ERRNO_CASE(ETXTBSY);
9191cb0ef41Sopenharmony_ci#endif
9201cb0ef41Sopenharmony_ci
9211cb0ef41Sopenharmony_ci#ifdef EXDEV
9221cb0ef41Sopenharmony_ci    ERRNO_CASE(EXDEV);
9231cb0ef41Sopenharmony_ci#endif
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_ci    default:
9261cb0ef41Sopenharmony_ci      return "";
9271cb0ef41Sopenharmony_ci  }
9281cb0ef41Sopenharmony_ci}
9291cb0ef41Sopenharmony_ci
9301cb0ef41Sopenharmony_civoid PerIsolateMessageListener(Local<Message> message, Local<Value> error) {
9311cb0ef41Sopenharmony_ci  Isolate* isolate = message->GetIsolate();
9321cb0ef41Sopenharmony_ci  switch (message->ErrorLevel()) {
9331cb0ef41Sopenharmony_ci    case Isolate::MessageErrorLevel::kMessageWarning: {
9341cb0ef41Sopenharmony_ci      Environment* env = Environment::GetCurrent(isolate);
9351cb0ef41Sopenharmony_ci      if (!env) {
9361cb0ef41Sopenharmony_ci        break;
9371cb0ef41Sopenharmony_ci      }
9381cb0ef41Sopenharmony_ci      Utf8Value filename(isolate, message->GetScriptOrigin().ResourceName());
9391cb0ef41Sopenharmony_ci      // (filename):(line) (message)
9401cb0ef41Sopenharmony_ci      std::stringstream warning;
9411cb0ef41Sopenharmony_ci      warning << *filename;
9421cb0ef41Sopenharmony_ci      warning << ":";
9431cb0ef41Sopenharmony_ci      warning << message->GetLineNumber(env->context()).FromMaybe(-1);
9441cb0ef41Sopenharmony_ci      warning << " ";
9451cb0ef41Sopenharmony_ci      v8::String::Utf8Value msg(isolate, message->Get());
9461cb0ef41Sopenharmony_ci      warning << *msg;
9471cb0ef41Sopenharmony_ci      USE(ProcessEmitWarningGeneric(env, warning.str().c_str(), "V8"));
9481cb0ef41Sopenharmony_ci      break;
9491cb0ef41Sopenharmony_ci    }
9501cb0ef41Sopenharmony_ci    case Isolate::MessageErrorLevel::kMessageError:
9511cb0ef41Sopenharmony_ci      TriggerUncaughtException(isolate, error, message);
9521cb0ef41Sopenharmony_ci      break;
9531cb0ef41Sopenharmony_ci  }
9541cb0ef41Sopenharmony_ci}
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_civoid SetPrepareStackTraceCallback(const FunctionCallbackInfo<Value>& args) {
9571cb0ef41Sopenharmony_ci  Realm* realm = Realm::GetCurrent(args);
9581cb0ef41Sopenharmony_ci  CHECK(args[0]->IsFunction());
9591cb0ef41Sopenharmony_ci  realm->set_prepare_stack_trace_callback(args[0].As<Function>());
9601cb0ef41Sopenharmony_ci}
9611cb0ef41Sopenharmony_ci
9621cb0ef41Sopenharmony_cistatic void SetSourceMapsEnabled(const FunctionCallbackInfo<Value>& args) {
9631cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
9641cb0ef41Sopenharmony_ci  CHECK(args[0]->IsBoolean());
9651cb0ef41Sopenharmony_ci  env->set_source_maps_enabled(args[0].As<Boolean>()->Value());
9661cb0ef41Sopenharmony_ci}
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_cistatic void SetGetSourceMapErrorSource(
9691cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
9701cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
9711cb0ef41Sopenharmony_ci  CHECK(args[0]->IsFunction());
9721cb0ef41Sopenharmony_ci  env->set_get_source_map_error_source(args[0].As<Function>());
9731cb0ef41Sopenharmony_ci}
9741cb0ef41Sopenharmony_ci
9751cb0ef41Sopenharmony_cistatic void SetMaybeCacheGeneratedSourceMap(
9761cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
9771cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
9781cb0ef41Sopenharmony_ci  CHECK(args[0]->IsFunction());
9791cb0ef41Sopenharmony_ci  env->set_maybe_cache_generated_source_map(args[0].As<Function>());
9801cb0ef41Sopenharmony_ci}
9811cb0ef41Sopenharmony_ci
9821cb0ef41Sopenharmony_cistatic void SetEnhanceStackForFatalException(
9831cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
9841cb0ef41Sopenharmony_ci  Realm* realm = Realm::GetCurrent(args);
9851cb0ef41Sopenharmony_ci  CHECK(args[0]->IsFunction());
9861cb0ef41Sopenharmony_ci  CHECK(args[1]->IsFunction());
9871cb0ef41Sopenharmony_ci  realm->set_enhance_fatal_stack_before_inspector(args[0].As<Function>());
9881cb0ef41Sopenharmony_ci  realm->set_enhance_fatal_stack_after_inspector(args[1].As<Function>());
9891cb0ef41Sopenharmony_ci}
9901cb0ef41Sopenharmony_ci
9911cb0ef41Sopenharmony_ci// Side effect-free stringification that will never throw exceptions.
9921cb0ef41Sopenharmony_cistatic void NoSideEffectsToString(const FunctionCallbackInfo<Value>& args) {
9931cb0ef41Sopenharmony_ci  Local<Context> context = args.GetIsolate()->GetCurrentContext();
9941cb0ef41Sopenharmony_ci  Local<String> detail_string;
9951cb0ef41Sopenharmony_ci  if (args[0]->ToDetailString(context).ToLocal(&detail_string))
9961cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(detail_string);
9971cb0ef41Sopenharmony_ci}
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_cistatic void TriggerUncaughtException(const FunctionCallbackInfo<Value>& args) {
10001cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
10011cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(isolate);
10021cb0ef41Sopenharmony_ci  Local<Value> exception = args[0];
10031cb0ef41Sopenharmony_ci  Local<Message> message = Exception::CreateMessage(isolate, exception);
10041cb0ef41Sopenharmony_ci  if (env != nullptr && env->abort_on_uncaught_exception()) {
10051cb0ef41Sopenharmony_ci    ReportFatalException(
10061cb0ef41Sopenharmony_ci        env, exception, message, EnhanceFatalException::kEnhance);
10071cb0ef41Sopenharmony_ci    Abort();
10081cb0ef41Sopenharmony_ci  }
10091cb0ef41Sopenharmony_ci  bool from_promise = args[1]->IsTrue();
10101cb0ef41Sopenharmony_ci  errors::TriggerUncaughtException(isolate, exception, message, from_promise);
10111cb0ef41Sopenharmony_ci}
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_civoid RegisterExternalReferences(ExternalReferenceRegistry* registry) {
10141cb0ef41Sopenharmony_ci  registry->Register(SetPrepareStackTraceCallback);
10151cb0ef41Sopenharmony_ci  registry->Register(SetGetSourceMapErrorSource);
10161cb0ef41Sopenharmony_ci  registry->Register(SetSourceMapsEnabled);
10171cb0ef41Sopenharmony_ci  registry->Register(SetMaybeCacheGeneratedSourceMap);
10181cb0ef41Sopenharmony_ci  registry->Register(SetEnhanceStackForFatalException);
10191cb0ef41Sopenharmony_ci  registry->Register(NoSideEffectsToString);
10201cb0ef41Sopenharmony_ci  registry->Register(TriggerUncaughtException);
10211cb0ef41Sopenharmony_ci}
10221cb0ef41Sopenharmony_ci
10231cb0ef41Sopenharmony_civoid Initialize(Local<Object> target,
10241cb0ef41Sopenharmony_ci                Local<Value> unused,
10251cb0ef41Sopenharmony_ci                Local<Context> context,
10261cb0ef41Sopenharmony_ci                void* priv) {
10271cb0ef41Sopenharmony_ci  SetMethod(context,
10281cb0ef41Sopenharmony_ci            target,
10291cb0ef41Sopenharmony_ci            "setPrepareStackTraceCallback",
10301cb0ef41Sopenharmony_ci            SetPrepareStackTraceCallback);
10311cb0ef41Sopenharmony_ci  SetMethod(context,
10321cb0ef41Sopenharmony_ci            target,
10331cb0ef41Sopenharmony_ci            "setGetSourceMapErrorSource",
10341cb0ef41Sopenharmony_ci            SetGetSourceMapErrorSource);
10351cb0ef41Sopenharmony_ci  SetMethod(context, target, "setSourceMapsEnabled", SetSourceMapsEnabled);
10361cb0ef41Sopenharmony_ci  SetMethod(context,
10371cb0ef41Sopenharmony_ci            target,
10381cb0ef41Sopenharmony_ci            "setMaybeCacheGeneratedSourceMap",
10391cb0ef41Sopenharmony_ci            SetMaybeCacheGeneratedSourceMap);
10401cb0ef41Sopenharmony_ci  SetMethod(context,
10411cb0ef41Sopenharmony_ci            target,
10421cb0ef41Sopenharmony_ci            "setEnhanceStackForFatalException",
10431cb0ef41Sopenharmony_ci            SetEnhanceStackForFatalException);
10441cb0ef41Sopenharmony_ci  SetMethodNoSideEffect(
10451cb0ef41Sopenharmony_ci      context, target, "noSideEffectsToString", NoSideEffectsToString);
10461cb0ef41Sopenharmony_ci  SetMethod(
10471cb0ef41Sopenharmony_ci      context, target, "triggerUncaughtException", TriggerUncaughtException);
10481cb0ef41Sopenharmony_ci}
10491cb0ef41Sopenharmony_ci
10501cb0ef41Sopenharmony_civoid DecorateErrorStack(Environment* env,
10511cb0ef41Sopenharmony_ci                        const errors::TryCatchScope& try_catch) {
10521cb0ef41Sopenharmony_ci  Local<Value> exception = try_catch.Exception();
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ci  if (!exception->IsObject()) return;
10551cb0ef41Sopenharmony_ci
10561cb0ef41Sopenharmony_ci  Local<Object> err_obj = exception.As<Object>();
10571cb0ef41Sopenharmony_ci
10581cb0ef41Sopenharmony_ci  if (IsExceptionDecorated(env, err_obj)) return;
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_ci  AppendExceptionLine(env, exception, try_catch.Message(), CONTEXTIFY_ERROR);
10611cb0ef41Sopenharmony_ci  TryCatchScope try_catch_scope(env);  // Ignore exceptions below.
10621cb0ef41Sopenharmony_ci  MaybeLocal<Value> stack = err_obj->Get(env->context(), env->stack_string());
10631cb0ef41Sopenharmony_ci  MaybeLocal<Value> maybe_value =
10641cb0ef41Sopenharmony_ci      err_obj->GetPrivate(env->context(), env->arrow_message_private_symbol());
10651cb0ef41Sopenharmony_ci
10661cb0ef41Sopenharmony_ci  Local<Value> arrow;
10671cb0ef41Sopenharmony_ci  if (!(maybe_value.ToLocal(&arrow) && arrow->IsString())) {
10681cb0ef41Sopenharmony_ci    return;
10691cb0ef41Sopenharmony_ci  }
10701cb0ef41Sopenharmony_ci
10711cb0ef41Sopenharmony_ci  if (stack.IsEmpty() || !stack.ToLocalChecked()->IsString()) {
10721cb0ef41Sopenharmony_ci    return;
10731cb0ef41Sopenharmony_ci  }
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_ci  Local<String> decorated_stack = String::Concat(
10761cb0ef41Sopenharmony_ci      env->isolate(),
10771cb0ef41Sopenharmony_ci      String::Concat(env->isolate(),
10781cb0ef41Sopenharmony_ci                     arrow.As<String>(),
10791cb0ef41Sopenharmony_ci                     FIXED_ONE_BYTE_STRING(env->isolate(), "\n")),
10801cb0ef41Sopenharmony_ci      stack.ToLocalChecked().As<String>());
10811cb0ef41Sopenharmony_ci  USE(err_obj->Set(env->context(), env->stack_string(), decorated_stack));
10821cb0ef41Sopenharmony_ci  err_obj->SetPrivate(
10831cb0ef41Sopenharmony_ci      env->context(), env->decorated_private_symbol(), True(env->isolate()));
10841cb0ef41Sopenharmony_ci}
10851cb0ef41Sopenharmony_ci
10861cb0ef41Sopenharmony_civoid TriggerUncaughtException(Isolate* isolate,
10871cb0ef41Sopenharmony_ci                              Local<Value> error,
10881cb0ef41Sopenharmony_ci                              Local<Message> message,
10891cb0ef41Sopenharmony_ci                              bool from_promise) {
10901cb0ef41Sopenharmony_ci  CHECK(!error.IsEmpty());
10911cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
10921cb0ef41Sopenharmony_ci
10931cb0ef41Sopenharmony_ci  if (message.IsEmpty()) message = Exception::CreateMessage(isolate, error);
10941cb0ef41Sopenharmony_ci
10951cb0ef41Sopenharmony_ci  CHECK(isolate->InContext());
10961cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
10971cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
10981cb0ef41Sopenharmony_ci  if (env == nullptr) {
10991cb0ef41Sopenharmony_ci    // This means that the exception happens before Environment is assigned
11001cb0ef41Sopenharmony_ci    // to the context e.g. when there is a SyntaxError in a per-context
11011cb0ef41Sopenharmony_ci    // script - which usually indicates that there is a bug because no JS
11021cb0ef41Sopenharmony_ci    // error is supposed to be thrown at this point.
11031cb0ef41Sopenharmony_ci    // Since we don't have access to Environment here, there is not
11041cb0ef41Sopenharmony_ci    // much we can do, so we just print whatever is useful and crash.
11051cb0ef41Sopenharmony_ci    PrintToStderrAndFlush(
11061cb0ef41Sopenharmony_ci        FormatCaughtException(isolate, context, error, message));
11071cb0ef41Sopenharmony_ci    Abort();
11081cb0ef41Sopenharmony_ci  }
11091cb0ef41Sopenharmony_ci
11101cb0ef41Sopenharmony_ci  // Invoke process._fatalException() to give user a chance to handle it.
11111cb0ef41Sopenharmony_ci  // We have to grab it from the process object since this has been
11121cb0ef41Sopenharmony_ci  // monkey-patchable.
11131cb0ef41Sopenharmony_ci  Local<Object> process_object = env->process_object();
11141cb0ef41Sopenharmony_ci  Local<String> fatal_exception_string = env->fatal_exception_string();
11151cb0ef41Sopenharmony_ci  Local<Value> fatal_exception_function =
11161cb0ef41Sopenharmony_ci      process_object->Get(env->context(),
11171cb0ef41Sopenharmony_ci                          fatal_exception_string).ToLocalChecked();
11181cb0ef41Sopenharmony_ci  // If the exception happens before process._fatalException is attached
11191cb0ef41Sopenharmony_ci  // during bootstrap, or if the user has patched it incorrectly, exit
11201cb0ef41Sopenharmony_ci  // the current Node.js instance.
11211cb0ef41Sopenharmony_ci  if (!fatal_exception_function->IsFunction()) {
11221cb0ef41Sopenharmony_ci    ReportFatalException(
11231cb0ef41Sopenharmony_ci        env, error, message, EnhanceFatalException::kDontEnhance);
11241cb0ef41Sopenharmony_ci    env->Exit(6);
11251cb0ef41Sopenharmony_ci    return;
11261cb0ef41Sopenharmony_ci  }
11271cb0ef41Sopenharmony_ci
11281cb0ef41Sopenharmony_ci  MaybeLocal<Value> maybe_handled;
11291cb0ef41Sopenharmony_ci  if (env->can_call_into_js()) {
11301cb0ef41Sopenharmony_ci    // We do not expect the global uncaught exception itself to throw any more
11311cb0ef41Sopenharmony_ci    // exceptions. If it does, exit the current Node.js instance.
11321cb0ef41Sopenharmony_ci    errors::TryCatchScope try_catch(env,
11331cb0ef41Sopenharmony_ci                                    errors::TryCatchScope::CatchMode::kFatal);
11341cb0ef41Sopenharmony_ci    // Explicitly disable verbose exception reporting -
11351cb0ef41Sopenharmony_ci    // if process._fatalException() throws an error, we don't want it to
11361cb0ef41Sopenharmony_ci    // trigger the per-isolate message listener which will call this
11371cb0ef41Sopenharmony_ci    // function and recurse.
11381cb0ef41Sopenharmony_ci    try_catch.SetVerbose(false);
11391cb0ef41Sopenharmony_ci    Local<Value> argv[2] = { error,
11401cb0ef41Sopenharmony_ci                             Boolean::New(env->isolate(), from_promise) };
11411cb0ef41Sopenharmony_ci
11421cb0ef41Sopenharmony_ci    maybe_handled = fatal_exception_function.As<Function>()->Call(
11431cb0ef41Sopenharmony_ci        env->context(), process_object, arraysize(argv), argv);
11441cb0ef41Sopenharmony_ci  }
11451cb0ef41Sopenharmony_ci
11461cb0ef41Sopenharmony_ci  // If process._fatalException() throws, we are now exiting the Node.js
11471cb0ef41Sopenharmony_ci  // instance so return to continue the exit routine.
11481cb0ef41Sopenharmony_ci  // TODO(joyeecheung): return a Maybe here to prevent the caller from
11491cb0ef41Sopenharmony_ci  // stepping on the exit.
11501cb0ef41Sopenharmony_ci  Local<Value> handled;
11511cb0ef41Sopenharmony_ci  if (!maybe_handled.ToLocal(&handled)) {
11521cb0ef41Sopenharmony_ci    return;
11531cb0ef41Sopenharmony_ci  }
11541cb0ef41Sopenharmony_ci
11551cb0ef41Sopenharmony_ci  // The global uncaught exception handler returns true if the user handles it
11561cb0ef41Sopenharmony_ci  // by e.g. listening to `uncaughtException`. In that case, continue program
11571cb0ef41Sopenharmony_ci  // execution.
11581cb0ef41Sopenharmony_ci  // TODO(joyeecheung): This has been only checking that the return value is
11591cb0ef41Sopenharmony_ci  // exactly false. Investigate whether this can be turned to an "if true"
11601cb0ef41Sopenharmony_ci  // similar to how the worker global uncaught exception handler handles it.
11611cb0ef41Sopenharmony_ci  if (!handled->IsFalse()) {
11621cb0ef41Sopenharmony_ci    return;
11631cb0ef41Sopenharmony_ci  }
11641cb0ef41Sopenharmony_ci
11651cb0ef41Sopenharmony_ci  // Now we are certain that the exception is fatal.
11661cb0ef41Sopenharmony_ci  ReportFatalException(env, error, message, EnhanceFatalException::kEnhance);
11671cb0ef41Sopenharmony_ci  RunAtExit(env);
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_ci  // If the global uncaught exception handler sets process.exitCode,
11701cb0ef41Sopenharmony_ci  // exit with that code. Otherwise, exit with 1.
11711cb0ef41Sopenharmony_ci  Local<String> exit_code = env->exit_code_string();
11721cb0ef41Sopenharmony_ci  Local<Value> code;
11731cb0ef41Sopenharmony_ci  if (process_object->Get(env->context(), exit_code).ToLocal(&code) &&
11741cb0ef41Sopenharmony_ci      code->IsInt32()) {
11751cb0ef41Sopenharmony_ci    env->Exit(code.As<Int32>()->Value());
11761cb0ef41Sopenharmony_ci  } else {
11771cb0ef41Sopenharmony_ci    env->Exit(1);
11781cb0ef41Sopenharmony_ci  }
11791cb0ef41Sopenharmony_ci}
11801cb0ef41Sopenharmony_ci
11811cb0ef41Sopenharmony_civoid TriggerUncaughtException(Isolate* isolate, const v8::TryCatch& try_catch) {
11821cb0ef41Sopenharmony_ci  // If the try_catch is verbose, the per-isolate message listener is going to
11831cb0ef41Sopenharmony_ci  // handle it (which is going to call into another overload of
11841cb0ef41Sopenharmony_ci  // TriggerUncaughtException()).
11851cb0ef41Sopenharmony_ci  if (try_catch.IsVerbose()) {
11861cb0ef41Sopenharmony_ci    return;
11871cb0ef41Sopenharmony_ci  }
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_ci  // If the user calls TryCatch::TerminateExecution() on this TryCatch
11901cb0ef41Sopenharmony_ci  // they must call CancelTerminateExecution() again before invoking
11911cb0ef41Sopenharmony_ci  // TriggerUncaughtException() because it will invoke
11921cb0ef41Sopenharmony_ci  // process._fatalException() in the JS land.
11931cb0ef41Sopenharmony_ci  CHECK(!try_catch.HasTerminated());
11941cb0ef41Sopenharmony_ci  CHECK(try_catch.HasCaught());
11951cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
11961cb0ef41Sopenharmony_ci  TriggerUncaughtException(isolate,
11971cb0ef41Sopenharmony_ci                           try_catch.Exception(),
11981cb0ef41Sopenharmony_ci                           try_catch.Message(),
11991cb0ef41Sopenharmony_ci                           false /* from_promise */);
12001cb0ef41Sopenharmony_ci}
12011cb0ef41Sopenharmony_ci
12021cb0ef41Sopenharmony_ci}  // namespace errors
12031cb0ef41Sopenharmony_ci
12041cb0ef41Sopenharmony_ci}  // namespace node
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ciNODE_BINDING_CONTEXT_AWARE_INTERNAL(errors, node::errors::Initialize)
12071cb0ef41Sopenharmony_ciNODE_BINDING_EXTERNAL_REFERENCE(errors,
12081cb0ef41Sopenharmony_ci                                node::errors::RegisterExternalReferences)
1209