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