Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(670)

Unified Diff: runtime/bin/loader.cc

Issue 2045023003: Fix deferred load errors / bug #26482 (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/loader.h ('k') | runtime/lib/lib_prefix.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/loader.cc
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index f43cf30056225291aa737c67d9a5b46e6d4d8145..a391b707e4abf65f1955b2b790b53b5b913dbf82 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -212,18 +212,20 @@ void Loader::BlockUntilComplete() {
}
-bool Loader::ProcessResultLocked(Loader::IOResult* result) {
- // A negative result tag indicates a loading error occurred in the service
- // isolate. The payload is a C string of the error message.
- if (result->tag < 0) {
- error_ =
- Dart_NewUnhandledExceptionError(
- Dart_NewStringFromUTF8(result->payload,
- result->payload_length));
-
- return false;
+static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) {
+ if (!Dart_IsNull(library) && !Dart_IsError(library)) {
+ ASSERT(Dart_IsLibrary(library));
+ Dart_Handle res = Dart_LibraryHandleError(library, error);
+ if (Dart_IsNull(res)) {
+ // Error was handled by library.
+ return true;
+ }
}
+ return false;
+}
+
+bool Loader::ProcessResultLocked(Loader::IOResult* result) {
// We have to copy everything we care about out of |result| because after
// dropping the lock below |result| may no longer valid.
Dart_Handle uri =
@@ -233,6 +235,25 @@ bool Loader::ProcessResultLocked(Loader::IOResult* result) {
library_uri =
Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri));
}
+
+ // A negative result tag indicates a loading error occurred in the service
+ // isolate. The payload is a C string of the error message.
+ if (result->tag < 0) {
+ Dart_Handle library = Dart_LookupLibrary(uri);
+ Dart_Handle error = Dart_NewStringFromUTF8(result->payload,
+ result->payload_length);
+ // If a library with the given uri exists, give it a chance to handle
+ // the error. If the load requests stems from a deferred library load,
+ // an IO error is not fatal.
+ if (LibraryHandleError(library, error)) {
+ return true;
+ }
+ // Fall through
+ error_ = Dart_NewUnhandledExceptionError(error);
+ return false;
+ }
+
+
// Check for payload and load accordingly.
bool is_snapshot = false;
const uint8_t* payload = result->payload;
@@ -402,8 +423,11 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
// The outer invocation of the tag handler for this isolate. We make the outer
// invocation block and allow any nested invocations to operate in parallel.
- bool blocking_call = !isolate_data->HasLoader();
+ const bool blocking_call = !isolate_data->HasLoader();
+ // If we are the outer invocation of the tag handler and the tag is an import
+ // this means that we are starting a deferred library load.
+ const bool is_deferred_import = blocking_call && (tag == Dart_kImportTag);
if (!isolate_data->HasLoader()) {
// The isolate doesn't have a loader -- this is the outer invocation which
// will block.
@@ -440,8 +464,23 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
delete loader;
// An error occurred during loading.
- if (Dart_IsError(error)) {
- return error;
+ if (!Dart_IsNull(error)) {
+ if (false && is_deferred_import) {
+ // This blocks handles transitive load errors caused by a deferred
+ // import. Non-transitive load errors are handled above (see callers of
+ // |LibraryHandleError|). To handle the transitive case, we give the
+ // originating deferred library an opportunity to handle it.
+ Dart_Handle deferred_library = Dart_LookupLibrary(url);
+ if (!LibraryHandleError(deferred_library, error)) {
+ // Library did not handle it, return to caller as an unhandled
+ // exception.
+ return Dart_NewUnhandledExceptionError(error);
+ }
+ } else {
+ // We got an error during loading but we aren't loading a deferred
+ // library, return the error to the caller.
+ return error;
+ }
}
// Finalize loading. This will complete any futures for completed deferred
« no previous file with comments | « runtime/bin/loader.h ('k') | runtime/lib/lib_prefix.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698