0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

Better c++ error handling

This commit is contained in:
Ryan Dahl 2018-07-05 17:33:20 -04:00
parent 41328d796e
commit 21e1425656
2 changed files with 37 additions and 8 deletions

View file

@ -47,20 +47,23 @@ static inline v8::Local<v8::String> v8_str(const char* x) {
void HandleException(v8::Local<v8::Context> context,
v8::Local<v8::Value> exception) {
auto* isolate = context->GetIsolate();
Deno* d = static_cast<Deno*>(isolate->GetData(0));
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
auto message = v8::Exception::CreateMessage(isolate, exception);
auto onerrorStr = v8::String::NewFromUtf8(isolate, "onerror");
auto onerror = context->Global()->Get(onerrorStr);
auto stack_trace = message->GetStackTrace();
auto line =
v8::Integer::New(isolate, message->GetLineNumber(context).FromJust());
auto column =
v8::Integer::New(isolate, message->GetStartColumn(context).FromJust());
if (onerror->IsFunction()) {
// window.onerror is set so we try to handle the exception in javascript.
auto func = v8::Local<v8::Function>::Cast(onerror);
v8::Local<v8::Value> args[5];
auto line =
v8::Integer::New(isolate, message->GetLineNumber(context).FromJust());
auto column =
v8::Integer::New(isolate, message->GetStartColumn(context).FromJust());
args[0] = exception->ToString();
args[1] = message->GetScriptResourceName();
args[2] = line;
@ -68,10 +71,36 @@ void HandleException(v8::Local<v8::Context> context,
args[4] = exception;
func->Call(context->Global(), 5, args);
/* message, source, lineno, colno, error */
} else {
} else if (!stack_trace.IsEmpty()) {
// No javascript onerror handler, but we do have a stack trace. Format it
// into a string and add to last_exception.
std::string msg;
v8::String::Utf8Value exceptionStr(isolate, exception);
printf("Unhandled Exception %s\n", ToCString(exceptionStr));
message->PrintCurrentStackTrace(isolate, stdout);
msg += ToCString(exceptionStr);
msg += "\n";
for (int i = 0; i < stack_trace->GetFrameCount(); ++i) {
auto frame = stack_trace->GetFrame(i);
v8::String::Utf8Value script_name(isolate, frame->GetScriptName());
int l = frame->GetLineNumber();
int c = frame->GetColumn();
char buf[512];
snprintf(buf, sizeof(buf), "%s %d:%d\n", ToCString(script_name), l, c);
msg += buf;
}
d->last_exception = msg;
} else {
// No javascript onerror handler, no stack trace. Format the little info we
// have into a string and add to last_exception.
v8::String::Utf8Value exceptionStr(isolate, exception);
v8::String::Utf8Value script_name(isolate,
message->GetScriptResourceName());
v8::String::Utf8Value line_str(isolate, line);
v8::String::Utf8Value col_str(isolate, column);
char buf[512];
snprintf(buf, sizeof(buf), "%s\n%s %s:%s\n", ToCString(exceptionStr),
ToCString(script_name), ToCString(line_str), ToCString(col_str));
d->last_exception = std::string(buf);
}
}

View file

@ -57,7 +57,7 @@ int main(int argc, char** argv) {
Deno* d = deno_new(NULL, MessagesFromJS);
bool r = deno_execute(d, "deno_main.js", "denoMain();");
if (!r) {
printf("Error! %s\n", deno_last_exception(d));
printf("%s\n", deno_last_exception(d));
exit(1);
}
deno_delete(d);