[dart_runner] Stop after unhandled exception and set return code.
Bug: FL-47
Change-Id: I733703e7ad7631bb304ce80bfb1dc073eab4a238
diff --git a/dart_message_handler.cc b/dart_message_handler.cc
index 851f52c..2263315 100644
--- a/dart_message_handler.cc
+++ b/dart_message_handler.cc
@@ -20,21 +20,16 @@
isolate_had_uncaught_exception_error_(false),
isolate_had_fatal_error_(false),
isolate_last_error_(kNoError),
- task_dispatcher_(nullptr),
- message_epilogue_(nullptr) {}
+ task_dispatcher_(nullptr) {}
DartMessageHandler::~DartMessageHandler() {
task_dispatcher_ = nullptr;
- message_epilogue_ = nullptr;
}
-void DartMessageHandler::Initialize(TaskDispatcher dispatcher,
- std::function<void()> message_epilogue) {
+void DartMessageHandler::Initialize(TaskDispatcher dispatcher) {
// Only can be called once.
- TONIC_CHECK(!task_dispatcher_);
+ TONIC_CHECK(!task_dispatcher_ && dispatcher);
task_dispatcher_ = dispatcher;
- message_epilogue_ = message_epilogue;
- TONIC_CHECK(task_dispatcher_);
Dart_SetMessageNotifyCallback(MessageNotifyCallback);
}
@@ -97,10 +92,12 @@
Dart_SetPausedOnStart(false);
// We've resumed, handle normal messages that are in the queue.
result = Dart_HandleMessage();
- if (message_epilogue_) {
- message_epilogue_();
- }
error = LogIfError(result);
+ dart_state->MessageEpilogue(result);
+ if (!Dart_CurrentIsolate()) {
+ isolate_exited_ = true;
+ return;
+ }
}
} else if (Dart_IsPausedOnExit()) {
// We are paused on isolate exit. Only handle service messages until we are
@@ -115,9 +112,6 @@
} else {
// We are processing messages normally.
result = Dart_HandleMessage();
- if (message_epilogue_) {
- message_epilogue_();
- }
// If the Dart program has set a return code, then it is intending to shut
// down by way of a fatal error, and so there is no need to emit a log
// message.
@@ -127,6 +121,11 @@
} else {
error = LogIfError(result);
}
+ dart_state->MessageEpilogue(result);
+ if (!Dart_CurrentIsolate()) {
+ isolate_exited_ = true;
+ return;
+ }
}
if (error) {
diff --git a/dart_message_handler.h b/dart_message_handler.h
index d217186..7ce7e38 100644
--- a/dart_message_handler.h
+++ b/dart_message_handler.h
@@ -22,8 +22,7 @@
~DartMessageHandler();
// Messages for the current isolate will be scheduled on |runner|.
- void Initialize(TaskDispatcher dispatcher,
- std::function<void()> message_epilogue = nullptr);
+ void Initialize(TaskDispatcher dispatcher);
// Handle an unhandled error. If the error is fatal then shut down the
// isolate. The message handler's isolate must be the current isolate.
@@ -57,7 +56,6 @@
bool isolate_had_fatal_error_;
DartErrorHandleType isolate_last_error_;
TaskDispatcher task_dispatcher_;
- std::function<void()> message_epilogue_;
private:
static void MessageNotifyCallback(Dart_Isolate dest_isolate);
diff --git a/dart_microtask_queue.cc b/dart_microtask_queue.cc
index c69e041..d102de0 100644
--- a/dart_microtask_queue.cc
+++ b/dart_microtask_queue.cc
@@ -80,6 +80,9 @@
if (error != kNoError) {
last_error_ = error;
}
+ dart_state->MessageEpilogue(result);
+ if (!Dart_CurrentIsolate())
+ return;
}
}
}
diff --git a/dart_state.cc b/dart_state.cc
index 3c0c8bd..886a16f 100644
--- a/dart_state.cc
+++ b/dart_state.cc
@@ -16,11 +16,13 @@
DartState::Scope::~Scope() {}
-DartState::DartState(int dirfd)
+DartState::DartState(int dirfd, std::function<void(Dart_Handle)> message_epilogue)
: isolate_(nullptr),
class_library_(new DartClassLibrary),
message_handler_(new DartMessageHandler()),
- file_loader_(new FileLoader(dirfd)) {}
+ file_loader_(new FileLoader(dirfd)),
+ message_epilogue_(message_epilogue),
+ weak_factory_(this) {}
DartState::~DartState() {}
diff --git a/dart_state.h b/dart_state.h
index 18aad93..2eedff2 100644
--- a/dart_state.h
+++ b/dart_state.h
@@ -36,7 +36,8 @@
DartApiScope api_scope_;
};
- DartState(int dirfd = -1);
+ DartState(int dirfd = -1,
+ std::function<void(Dart_Handle)> message_epilogue = nullptr);
virtual ~DartState();
static DartState* From(Dart_Isolate isolate);
@@ -51,6 +52,11 @@
DartMessageHandler& message_handler() { return *message_handler_; }
FileLoader& file_loader() { return *file_loader_; }
+ void MessageEpilogue(Dart_Handle message_result) {
+ if (message_epilogue_) {
+ message_epilogue_(message_result);
+ }
+ }
void SetReturnCode(uint32_t return_code);
void SetReturnCodeCallback(std::function<void(uint32_t)> callback);
bool has_set_return_code() const { return has_set_return_code_; }
@@ -66,6 +72,7 @@
std::unique_ptr<DartClassLibrary> class_library_;
std::unique_ptr<DartMessageHandler> message_handler_;
std::unique_ptr<FileLoader> file_loader_;
+ std::function<void(Dart_Handle)> message_epilogue_;
std::function<void(uint32_t)> set_return_code_callback_;
bool has_set_return_code_;
diff --git a/logging/dart_error.cc b/logging/dart_error.cc
index 45a4333..e2c62ef 100644
--- a/logging/dart_error.cc
+++ b/logging/dart_error.cc
@@ -31,4 +31,16 @@
}
}
+int GetErrorExitCode(Dart_Handle handle) {
+ if (Dart_IsCompilationError(handle)) {
+ return 254; // dart::bin::kCompilationErrorExitCode
+ } else if (Dart_IsApiError(handle)) {
+ return 253; // dart::bin::kApiErrorExitCode
+ } else if (Dart_IsError(handle)) {
+ return 255; // dart::bin::kErrorExitCode
+ } else {
+ return 0;
+ }
+}
+
} // namespace tonic
diff --git a/logging/dart_error.h b/logging/dart_error.h
index 7e3bb30..5bd8159 100644
--- a/logging/dart_error.h
+++ b/logging/dart_error.h
@@ -24,6 +24,8 @@
DartErrorHandleType GetErrorHandleType(Dart_Handle handle);
+int GetErrorExitCode(Dart_Handle handle);
+
} // namespace tonic
#endif // LIB_TONIC_DART_ERROR_H_