summaryrefslogtreecommitdiff
path: root/src/binding.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-07-05 17:33:20 -0400
committerRyan Dahl <ry@tinyclouds.org>2018-07-06 12:22:11 -0400
commit21e1425656ccebb8d31da95acd83991fb7d728fd (patch)
tree23be07136bff0e17926edcf06e2ae46ddf784daa /src/binding.cc
parent41328d796e440dd52198c8f30111419cbec81d6b (diff)
Better c++ error handling
Diffstat (limited to 'src/binding.cc')
-rw-r--r--src/binding.cc41
1 files changed, 35 insertions, 6 deletions
diff --git a/src/binding.cc b/src/binding.cc
index cd8c67ef5..d8de138c1 100644
--- a/src/binding.cc
+++ b/src/binding.cc
@@ -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 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);
+ 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);
- printf("Unhandled Exception %s\n", ToCString(exceptionStr));
- message->PrintCurrentStackTrace(isolate, stdout);
+ 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);
}
}