11#include < cerrno>
22#include < cstdarg>
33
4+ #include " debug_utils-inl.h"
45#include " node_errors.h"
56#include " node_internals.h"
67#ifdef NODE_REPORT
1011#include " node_v8_platform-inl.h"
1112#include " util-inl.h"
1213
13- #ifdef __ANDROID__
14- #include < android/log.h>
15- #endif
16-
1714namespace node {
1815
1916using errors::TryCatchScope;
@@ -54,8 +51,6 @@ namespace per_process {
5451static Mutex tty_mutex;
5552} // namespace per_process
5653
57- static const int kMaxErrorSourceLength = 1024 ;
58-
5954static std::string GetErrorSource (Isolate* isolate,
6055 Local<Context> context,
6156 Local<Message> message,
@@ -107,41 +102,35 @@ static std::string GetErrorSource(Isolate* isolate,
107102 end -= script_start;
108103 }
109104
110- int max_off = kMaxErrorSourceLength - 2 ;
111-
112- char buf[kMaxErrorSourceLength ];
113- int off = snprintf (buf,
114- kMaxErrorSourceLength ,
115- " %s:%i\n %s\n " ,
116- filename_string,
117- linenum,
118- sourceline.c_str ());
119- CHECK_GE (off, 0 );
120- if (off > max_off) {
121- off = max_off;
122- }
105+ std::string buf = SPrintF (" %s:%i\n %s\n " ,
106+ filename_string,
107+ linenum,
108+ sourceline.c_str ());
109+ CHECK_GT (buf.size (), 0 );
123110
111+ constexpr int kUnderlineBufsize = 1020 ;
112+ char underline_buf[kUnderlineBufsize + 4 ];
113+ int off = 0 ;
124114 // Print wavy underline (GetUnderline is deprecated).
125115 for (int i = 0 ; i < start; i++) {
126- if (sourceline[i] == ' \0 ' || off >= max_off ) {
116+ if (sourceline[i] == ' \0 ' || off >= kUnderlineBufsize ) {
127117 break ;
128118 }
129- CHECK_LT (off, max_off );
130- buf [off++] = (sourceline[i] == ' \t ' ) ? ' \t ' : ' ' ;
119+ CHECK_LT (off, kUnderlineBufsize );
120+ underline_buf [off++] = (sourceline[i] == ' \t ' ) ? ' \t ' : ' ' ;
131121 }
132122 for (int i = start; i < end; i++) {
133- if (sourceline[i] == ' \0 ' || off >= max_off ) {
123+ if (sourceline[i] == ' \0 ' || off >= kUnderlineBufsize ) {
134124 break ;
135125 }
136- CHECK_LT (off, max_off );
137- buf [off++] = ' ^' ;
126+ CHECK_LT (off, kUnderlineBufsize );
127+ underline_buf [off++] = ' ^' ;
138128 }
139- CHECK_LE (off, max_off);
140- buf[off] = ' \n ' ;
141- buf[off + 1 ] = ' \0 ' ;
129+ CHECK_LE (off, kUnderlineBufsize );
130+ underline_buf[off++] = ' \n ' ;
142131
143132 *added_exception_line = true ;
144- return std::string (buf );
133+ return buf + std::string (underline_buf, off );
145134}
146135
147136void PrintStackTrace (Isolate* isolate, Local<StackTrace> stack) {
@@ -154,9 +143,9 @@ void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
154143
155144 if (stack_frame->IsEval ()) {
156145 if (stack_frame->GetScriptId () == Message::kNoScriptIdInfo ) {
157- fprintf (stderr, " at [eval]:%i:%i\n " , line_number, column);
146+ FPrintF (stderr, " at [eval]:%i:%i\n " , line_number, column);
158147 } else {
159- fprintf (stderr,
148+ FPrintF (stderr,
160149 " at [eval] (%s:%i:%i)\n " ,
161150 *script_name,
162151 line_number,
@@ -166,12 +155,12 @@ void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
166155 }
167156
168157 if (fn_name_s.length () == 0 ) {
169- fprintf (stderr, " at %s:%i:%i\n " , * script_name, line_number, column);
158+ FPrintF (stderr, " at %s:%i:%i\n " , script_name, line_number, column);
170159 } else {
171- fprintf (stderr,
160+ FPrintF (stderr,
172161 " at %s (%s:%i:%i)\n " ,
173- * fn_name_s,
174- * script_name,
162+ fn_name_s,
163+ script_name,
175164 line_number,
176165 column);
177166 }
@@ -189,8 +178,8 @@ void PrintException(Isolate* isolate,
189178 bool added_exception_line = false ;
190179 std::string source =
191180 GetErrorSource (isolate, context, message, &added_exception_line);
192- fprintf (stderr, " %s\n " , source. c_str () );
193- fprintf (stderr, " %s\n " , * reason);
181+ FPrintF (stderr, " %s\n " , source);
182+ FPrintF (stderr, " %s\n " , reason);
194183
195184 Local<v8::StackTrace> stack = message->GetStackTrace ();
196185 if (!stack.IsEmpty ()) PrintStackTrace (isolate, stack);
@@ -235,7 +224,7 @@ void AppendExceptionLine(Environment* env,
235224 env->set_printed_error (true );
236225
237226 ResetStdio ();
238- PrintErrorString ( " \n %s" , source. c_str () );
227+ FPrintF (stderr, " \n %s" , source);
239228 return ;
240229 }
241230
@@ -347,10 +336,10 @@ static void ReportFatalException(Environment* env,
347336 // range errors have a trace member set to undefined
348337 if (trace.length () > 0 && !stack_trace->IsUndefined ()) {
349338 if (arrow.IsEmpty () || !arrow->IsString () || decorated) {
350- PrintErrorString ( " %s\n " , * trace);
339+ FPrintF (stderr, " %s\n " , trace);
351340 } else {
352341 node::Utf8Value arrow_string (env->isolate (), arrow);
353- PrintErrorString ( " %s\n %s\n " , * arrow_string, * trace);
342+ FPrintF (stderr, " %s\n %s\n " , arrow_string, trace);
354343 }
355344 } else {
356345 // this really only happens for RangeErrors, since they're the only
@@ -368,76 +357,40 @@ static void ReportFatalException(Environment* env,
368357 if (message.IsEmpty () || message.ToLocalChecked ()->IsUndefined () ||
369358 name.IsEmpty () || name.ToLocalChecked ()->IsUndefined ()) {
370359 // Not an error object. Just print as-is.
371- String ::Utf8Value message (env->isolate (), error);
360+ node ::Utf8Value message (env->isolate (), error);
372361
373- PrintErrorString ( " %s\n " ,
374- *message ? * message : " <toString() threw exception>" );
362+ FPrintF (stderr, " %s\n " ,
363+ *message ? message. ToString () : " <toString() threw exception>" );
375364 } else {
376365 node::Utf8Value name_string (env->isolate (), name.ToLocalChecked ());
377366 node::Utf8Value message_string (env->isolate (), message.ToLocalChecked ());
378367
379368 if (arrow.IsEmpty () || !arrow->IsString () || decorated) {
380- PrintErrorString ( " %s: %s\n " , * name_string, * message_string);
369+ FPrintF (stderr, " %s: %s\n " , name_string, message_string);
381370 } else {
382371 node::Utf8Value arrow_string (env->isolate (), arrow);
383- PrintErrorString (
384- " %s\n %s: %s\n " , * arrow_string, * name_string, * message_string);
372+ FPrintF (stderr,
373+ " %s\n %s: %s\n " , arrow_string, name_string, message_string);
385374 }
386375 }
387376
388377 if (!env->options ()->trace_uncaught ) {
389- PrintErrorString ( " (Use `node --trace-uncaught ...` to show "
390- " where the exception was thrown)\n " );
378+ FPrintF (stderr, " (Use `node --trace-uncaught ...` to show "
379+ " where the exception was thrown)\n " );
391380 }
392381 }
393382
394383 if (env->options ()->trace_uncaught ) {
395384 Local<StackTrace> trace = message->GetStackTrace ();
396385 if (!trace.IsEmpty ()) {
397- PrintErrorString ( " Thrown at:\n " );
386+ FPrintF (stderr, " Thrown at:\n " );
398387 PrintStackTrace (env->isolate (), trace);
399388 }
400389 }
401390
402391 fflush (stderr);
403392}
404393
405- void PrintErrorString (const char * format, ...) {
406- va_list ap;
407- va_start (ap, format);
408- #ifdef _WIN32
409- HANDLE stderr_handle = GetStdHandle (STD_ERROR_HANDLE);
410-
411- // Check if stderr is something other than a tty/console
412- if (stderr_handle == INVALID_HANDLE_VALUE || stderr_handle == nullptr ||
413- uv_guess_handle (_fileno (stderr)) != UV_TTY) {
414- vfprintf (stderr, format, ap);
415- va_end (ap);
416- return ;
417- }
418-
419- // Fill in any placeholders
420- int n = _vscprintf (format, ap);
421- std::vector<char > out (n + 1 );
422- vsprintf (out.data (), format, ap);
423-
424- // Get required wide buffer size
425- n = MultiByteToWideChar (CP_UTF8, 0 , out.data (), -1 , nullptr , 0 );
426-
427- std::vector<wchar_t > wbuf (n);
428- MultiByteToWideChar (CP_UTF8, 0 , out.data (), -1 , wbuf.data (), n);
429-
430- // Don't include the null character in the output
431- CHECK_GT (n, 0 );
432- WriteConsoleW (stderr_handle, wbuf.data (), n - 1 , nullptr , nullptr );
433- #elif defined(__ANDROID__)
434- __android_log_vprint (ANDROID_LOG_ERROR, " nodejs" , format, ap);
435- #else
436- vfprintf (stderr, format, ap);
437- #endif
438- va_end (ap);
439- }
440-
441394[[noreturn]] void FatalError (const char * location, const char * message) {
442395 OnFatalError (location, message);
443396 // to suppress compiler warning
@@ -446,9 +399,9 @@ void PrintErrorString(const char* format, ...) {
446399
447400void OnFatalError (const char * location, const char * message) {
448401 if (location) {
449- PrintErrorString ( " FATAL ERROR: %s %s\n " , location, message);
402+ FPrintF (stderr, " FATAL ERROR: %s %s\n " , location, message);
450403 } else {
451- PrintErrorString ( " FATAL ERROR: %s\n " , message);
404+ FPrintF (stderr, " FATAL ERROR: %s\n " , message);
452405 }
453406#ifdef NODE_REPORT
454407 Isolate* isolate = Isolate::GetCurrent ();
0 commit comments