diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni
index e8a85748adec9..20ca0bb90f698 100644
--- a/third_party/blink/renderer/bindings/bindings.gni
+++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -17,6 +17,7 @@ bindings_core_v8_files =
                     "core/v8/binding_security.h",
                     "core/v8/boxed_v8_module.h",
                     "core/v8/callback_promise_adapter.h",
+                    "core/v8/classic_evaluation_result.h",
                     "core/v8/custom/v8_custom_xpath_ns_resolver.cc",
                     "core/v8/custom/v8_custom_xpath_ns_resolver.h",
                     "core/v8/custom/v8_dev_tools_host_custom.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/classic_evaluation_result.h b/third_party/blink/renderer/bindings/core/v8/classic_evaluation_result.h
new file mode 100644
index 0000000000000..61edac35d100b
--- /dev/null
+++ b/third_party/blink/renderer/bindings/core/v8/classic_evaluation_result.h
@@ -0,0 +1,61 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_CLASSIC_EVALUATION_RESULT_H_
+#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_CLASSIC_EVALUATION_RESULT_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_source_location_type.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
+#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// ClassicEvaluationResult encapsulates the result of a classic script
+// evaluation.
+// - If IsEmpty() is false:
+//     A script is evaluated successfully.
+//     No exceptions are thrown.
+//     GetValue() returns a non-Empty value.
+// - If IsEmpty() is true:
+//     Script evaluation failed (compile error, evaluation error, or so).
+//     An exception might or might not be thrown in V8.
+//     Unlike v8::MaybeLocal<>, there are cases where no exceptions are thrown
+//     to V8 while returning an Empty ClassicEvaluationResult, like when:
+//     - An exception is thrown during script evaluation but caught and passed
+//       to https://html.spec.whatwg.org/C/#report-the-error, instead of
+//       being rethrown, or
+//     - Script evaluation is skipped due to checks within Blink.
+//
+// TODO(crbug/1111134): Consider merging with ModuleEvaluationResult later.
+// Right now classic and module evaluation paths are not yet merged, and
+// top-level await (crbug/1022182) will modify ModuleEvaluationResult.
+class CORE_EXPORT ClassicEvaluationResult final {
+  STACK_ALLOCATED();
+
+ public:
+  ClassicEvaluationResult() = default;
+  explicit ClassicEvaluationResult(v8::Local<v8::Value> value) : value_(value) {
+    DCHECK(!IsEmpty());
+  }
+
+  bool IsEmpty() const { return value_.IsEmpty(); }
+  v8::Local<v8::Value> GetValue() const {
+    DCHECK(!IsEmpty());
+    return value_;
+  }
+
+ private:
+  v8::Local<v8::Value> value_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_CLASSIC_EVALUATION_RESULT_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index c0ed21b47e6b7..b1f64a26a3015 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/core/events/error_event.h"
 #include "third_party/blink/renderer/core/execution_context/agent.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -54,6 +55,7 @@
 #include "third_party/blink/renderer/platform/bindings/origin_trial_features.h"
 #include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
@@ -62,48 +64,12 @@
 
 namespace blink {
 
-class WorkerOrWorkletScriptController::ExecutionState final {
-  STACK_ALLOCATED();
-
- public:
-  explicit ExecutionState(WorkerOrWorkletScriptController* controller)
-      : had_exception(false),
-        error_event_from_imported_script_(nullptr),
-        controller_(controller),
-        outer_state_(controller->execution_state_) {
-    controller_->execution_state_ = this;
-  }
-
-  ~ExecutionState() { controller_->execution_state_ = outer_state_; }
-
-  bool had_exception;
-  String error_message;
-  std::unique_ptr<SourceLocation> location_;
-  ScriptValue exception;
-  ErrorEvent* error_event_from_imported_script_;
-
-  // A ExecutionState context is stack allocated by
-  // WorkerOrWorkletScriptController::evaluate(), with the contoller using it
-  // during script evaluation. To handle nested evaluate() uses,
-  // ExecutionStates are chained together;
-  // |outer_state_| keeps a pointer to the context object one level out
-  // (or 0, if outermost.) Upon return from evaluate(), the
-  // WorkerOrWorkletScriptController's ExecutionState is popped and the
-  // previous one restored (see above dtor.)
-  //
-  // With Oilpan, |outer_state_| isn't traced. It'll be "up the stack"
-  // and its fields will be traced when scanning the stack.
-  WorkerOrWorkletScriptController* controller_;
-  ExecutionState* outer_state_;
-};
-
 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(
     WorkerOrWorkletGlobalScope* global_scope,
     v8::Isolate* isolate)
     : global_scope_(global_scope),
       isolate_(isolate),
-      rejected_promises_(RejectedPromises::Create()),
-      execution_state_(nullptr) {
+      rejected_promises_(RejectedPromises::Create()) {
   DCHECK(isolate);
   world_ =
       DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
@@ -345,109 +311,120 @@ void WorkerOrWorkletScriptController::DisableEvalInternal(
       V8String(isolate_, error_message));
 }
 
-v8::Local<v8::Value> WorkerOrWorkletScriptController::EvaluateInternal(
+// https://html.spec.whatwg.org/C/#run-a-classic-script
+ClassicEvaluationResult WorkerOrWorkletScriptController::EvaluateAndReturnValue(
     const ScriptSourceCode& source_code,
     SanitizeScriptErrors sanitize_script_errors,
-    V8CacheOptions v8_cache_options) {
-  DCHECK(IsContextInitialized());
-  DCHECK(is_ready_to_evaluate_);
-
-  TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data",
-               inspector_evaluate_script_event::Data(
-                   nullptr, source_code.Url(), source_code.StartPosition()));
-
-  v8::TryCatch block(isolate_);
-
-  // TODO(crbug/1114994): Plumb this from ClassicScript.
-  const KURL base_url = source_code.Url();
-
-  // Use default ReferrerScriptInfo here, as
-  // - A work{er,let} script doesn't have a nonce, and
-  // - a work{er,let} script is always "not parser inserted".
-  // TODO(crbug/1114988): After crbug/1114988 is fixed, this can be the
-  // default ScriptFetchOptions(). Currently the default ScriptFetchOptions()
-  // is not used because it has CredentialsMode::kOmit.
-  // TODO(crbug/1114989): Plumb this from ClassicScript.
-  ScriptFetchOptions script_fetch_options(
-      String(), IntegrityMetadataSet(), String(),
-      ParserDisposition::kNotParserInserted,
-      network::mojom::CredentialsMode::kSameOrigin,
-      network::mojom::ReferrerPolicy::kDefault,
-      mojom::blink::FetchImportanceMode::kImportanceAuto);
-
-  v8::MaybeLocal<v8::Value> maybe_result = V8ScriptRunner::CompileAndRunScript(
-      isolate_, script_state_, global_scope_, source_code, base_url,
-      sanitize_script_errors, script_fetch_options, v8_cache_options);
-
-  if (!block.CanContinue()) {
-    ForbidExecution();
-    return v8::Local<v8::Value>();
-  }
-
-  if (block.HasCaught()) {
-    v8::Local<v8::Message> message = block.Message();
-    execution_state_->had_exception = true;
-    execution_state_->error_message = ToCoreString(message->Get());
-    execution_state_->location_ = SourceLocation::FromMessage(
-        isolate_, message, ExecutionContext::From(script_state_));
-    execution_state_->exception =
-        ScriptValue(script_state_->GetIsolate(), block.Exception());
-    block.Reset();
-  } else {
-    execution_state_->had_exception = false;
-  }
-
-  v8::Local<v8::Value> result;
-  if (!maybe_result.ToLocal(&result))
-    return v8::Local<v8::Value>();
-
-  return result;
-}
-
-v8::Local<v8::Value> WorkerOrWorkletScriptController::EvaluateAndReturnValue(
-    const ScriptSourceCode& source_code,
-    SanitizeScriptErrors sanitize_script_errors,
-    ErrorEvent** error_event,
-    V8CacheOptions v8_cache_options) {
+    V8CacheOptions v8_cache_options,
+    RethrowErrorsOption rethrow_errors) {
   if (IsExecutionForbidden())
-    return v8::Local<v8::Value>();
+    return ClassicEvaluationResult();
 
-  ExecutionState state(this);
-  v8::Local<v8::Value> result =
-      EvaluateInternal(source_code, sanitize_script_errors, v8_cache_options);
-  if (IsExecutionForbidden())
-    return v8::Local<v8::Value>();
+  // Scope for |TRACE_EVENT1| and |v8::TryCatch| below.
+  {
+    DCHECK(IsContextInitialized());
+    DCHECK(is_ready_to_evaluate_);
 
-  if (state.had_exception) {
-    if (error_event) {
-      if (state.error_event_from_imported_script_) {
-        // Propagate inner error event outwards.
-        *error_event = state.error_event_from_imported_script_;
-        state.error_event_from_imported_script_ = nullptr;
-        return v8::Local<v8::Value>();
-      }
-      if (sanitize_script_errors == SanitizeScriptErrors::kSanitize) {
-        *error_event = ErrorEvent::CreateSanitizedError(script_state_);
-      } else {
-        *error_event =
-            ErrorEvent::Create(state.error_message, state.location_->Clone(),
-                               state.exception, world_.get());
-      }
-    } else {
-      ErrorEvent* event = nullptr;
-      if (state.error_event_from_imported_script_) {
-        event = state.error_event_from_imported_script_;
-        state.error_event_from_imported_script_ = nullptr;
-      } else {
-        event =
-            ErrorEvent::Create(state.error_message, state.location_->Clone(),
-                               state.exception, world_.get());
-      }
-      global_scope_->DispatchErrorEvent(event, sanitize_script_errors);
+    TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data",
+                 inspector_evaluate_script_event::Data(
+                     nullptr, source_code.Url(), source_code.StartPosition()));
+
+    v8::TryCatch block(isolate_);
+
+    // Step 8.3. Otherwise, rethrow errors is false. Perform the following
+    // steps: [spec text]
+    // Step 8.3.1. Report the exception given by evaluationStatus.[[Value]]
+    // for script. [spec text]
+    //
+    // This will be done inside V8 (inside V8ScriptRunner::CompileAndRunScript()
+    // below) by setting TryCatch::SetVerbose(true) here.
+    if (!rethrow_errors.ShouldRethrow()) {
+      block.SetVerbose(true);
+    }
+
+    // TODO(crbug/1114994): Plumb this from ClassicScript.
+    const KURL base_url = source_code.Url();
+
+    // Use default ReferrerScriptInfo here, as
+    // - A work{er,let} script doesn't have a nonce, and
+    // - a work{er,let} script is always "not parser inserted".
+    // TODO(crbug/1114988): After crbug/1114988 is fixed, this can be the
+    // default ScriptFetchOptions(). Currently the default ScriptFetchOptions()
+    // is not used because it has CredentialsMode::kOmit.
+    // TODO(crbug/1114989): Plumb this from ClassicScript.
+    ScriptFetchOptions script_fetch_options(
+        String(), IntegrityMetadataSet(), String(),
+        ParserDisposition::kNotParserInserted,
+        network::mojom::CredentialsMode::kSameOrigin,
+        network::mojom::ReferrerPolicy::kDefault,
+        mojom::blink::FetchImportanceMode::kImportanceAuto);
+
+    v8::MaybeLocal<v8::Value> maybe_result =
+        V8ScriptRunner::CompileAndRunScript(
+            isolate_, script_state_, global_scope_, source_code, base_url,
+            sanitize_script_errors, script_fetch_options, v8_cache_options);
+
+    // TODO(crbug/1114601): Investigate whether to check CanContinue() in other
+    // script evaluation code paths.
+    if (!block.CanContinue()) {
+      ForbidExecution();
+    }
+
+    if (IsExecutionForbidden()) {
+      return ClassicEvaluationResult();
+    }
+
+    if (!block.HasCaught()) {
+      // Step 10. If evaluationStatus is a normal completion, then return
+      // evaluationStatus. [spec text]
+      v8::Local<v8::Value> result;
+      if (!maybe_result.ToLocal(&result))
+        return ClassicEvaluationResult();
+
+      return ClassicEvaluationResult(result);
+    }
+
+    DCHECK(maybe_result.IsEmpty());
+
+    if (rethrow_errors.ShouldRethrow() &&
+        sanitize_script_errors == SanitizeScriptErrors::kDoNotSanitize) {
+      // Step 8.1. If rethrow errors is true and script's muted errors is
+      // false, then: [spec text]
+      //
+      // Step 8.1.2. Rethrow evaluationStatus.[[Value]]. [spec text]
+      //
+      // We rethrow exceptions reported from importScripts() here. The
+      // original filename/lineno/colno information (which points inside of
+      // imported scripts) is kept through ReThrow(), and will be eventually
+      // reported to WorkerGlobalScope.onerror via `TryCatch::SetVerbose(true)`
+      // called at top-level worker script evaluation.
+      block.ReThrow();
+      return ClassicEvaluationResult();
     }
-    return v8::Local<v8::Value>();
   }
-  return result;
+  // |v8::TryCatch| is (and should be) exited, before ThrowException() below.
+
+  if (rethrow_errors.ShouldRethrow()) {
+    // kDoNotSanitize case is processed and early-exited above.
+    DCHECK_EQ(sanitize_script_errors, SanitizeScriptErrors::kSanitize);
+
+    // Step 8.2. If rethrow errors is true and script's muted errors is
+    // true, then: [spec text]
+    //
+    // Step 8.2.2. Throw a "NetworkError" DOMException. [spec text]
+    //
+    // We don't supply any message here to avoid leaking details of muted
+    // errors.
+    V8ThrowException::ThrowException(
+        isolate_, V8ThrowDOMException::CreateOrEmpty(
+                      isolate_, DOMExceptionCode::kNetworkError,
+                      rethrow_errors.Message()));
+    return ClassicEvaluationResult();
+  }
+
+  // #report-the-error for rethrow errors == true is already handled via
+  // |TryCatch::SetVerbose(true)| above.
+  return ClassicEvaluationResult();
 }
 
 void WorkerOrWorkletScriptController::ForbidExecution() {
@@ -481,15 +458,6 @@ void WorkerOrWorkletScriptController::DisableEval(const String& error_message) {
   disable_eval_pending_ = error_message;
 }
 
-void WorkerOrWorkletScriptController::RethrowExceptionFromImportedScript(
-    ErrorEvent* error_event,
-    ExceptionState& exception_state) {
-  if (execution_state_)
-    execution_state_->error_event_from_imported_script_ = error_event;
-  exception_state.RethrowV8Exception(
-      error_event->error(script_state_).V8ValueFor(script_state_));
-}
-
 void WorkerOrWorkletScriptController::Trace(Visitor* visitor) const {
   visitor->Trace(global_scope_);
   visitor->Trace(script_state_);
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
index d901e4aecd775..23fc7bdfc7a9f 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
@@ -32,6 +32,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_WORKER_OR_WORKLET_SCRIPT_CONTROLLER_H_
 
 #include "base/macros.h"
+#include "third_party/blink/renderer/bindings/core/v8/classic_evaluation_result.h"
 #include "third_party/blink/renderer/bindings/core/v8/rejected_promises.h"
 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -44,8 +45,6 @@
 
 namespace blink {
 
-class ErrorEvent;
-class ExceptionState;
 class ScriptSourceCode;
 class WorkerOrWorkletGlobalScope;
 
@@ -58,13 +57,50 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
 
   bool IsExecutionForbidden() const;
 
-  // Returns a non-Empty value if the evaluation completed with no uncaught
-  // exception. Callers should enter ScriptState::Scope before calling this.
-  v8::Local<v8::Value> EvaluateAndReturnValue(
+  // Rethrow errors flag in
+  // https://html.spec.whatwg.org/C/#run-a-classic-script
+  class RethrowErrorsOption final {
+    STACK_ALLOCATED();
+
+   public:
+    RethrowErrorsOption(RethrowErrorsOption&&) = default;
+    RethrowErrorsOption& operator=(RethrowErrorsOption&&) = default;
+
+    RethrowErrorsOption(const RethrowErrorsOption&) = delete;
+    RethrowErrorsOption& operator=(const RethrowErrorsOption&) = delete;
+
+    // Rethrow errors flag is false.
+    static RethrowErrorsOption DoNotRethrow() {
+      return RethrowErrorsOption(base::nullopt);
+    }
+
+    // Rethrow errors flag is true. When rethrowing, a NetworkError with
+    // `message` is thrown. This is used only for importScripts(), and
+    // `message` is used to throw NetworkErrors with the same message text,
+    // no matter whether the NetworkError is thrown inside or outside
+    // EvaluateAndReturnValue().
+    static RethrowErrorsOption Rethrow(const String& message) {
+      return RethrowErrorsOption(message);
+    }
+
+    bool ShouldRethrow() const { return static_cast<bool>(message_); }
+    String Message() const { return *message_; }
+
+   private:
+    explicit RethrowErrorsOption(base::Optional<String> message)
+        : message_(std::move(message)) {}
+
+    // `nullopt` <=> rethrow errors is false.
+    base::Optional<String> message_;
+  };
+
+  // https://html.spec.whatwg.org/C/#run-a-classic-script
+  // Callers should enter ScriptState::Scope before calling this.
+  ClassicEvaluationResult EvaluateAndReturnValue(
       const ScriptSourceCode&,
       SanitizeScriptErrors sanitize_script_errors,
-      ErrorEvent** = nullptr,
-      V8CacheOptions = kV8CacheOptionsDefault);
+      V8CacheOptions = kV8CacheOptionsDefault,
+      RethrowErrorsOption = RethrowErrorsOption::DoNotRethrow());
 
   // Prevents future JavaScript execution.
   void ForbidExecution();
@@ -81,8 +117,6 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
   // before Evaluate().
   void PrepareForEvaluation();
 
-  // Used by WorkerGlobalScope:
-  void RethrowExceptionFromImportedScript(ErrorEvent*, ExceptionState&);
   // Disables `eval()` on JavaScript. This must be called before Evaluate().
   void DisableEval(const String&);
 
@@ -106,14 +140,8 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
   }
 
  private:
-  class ExecutionState;
-
   void DisableEvalInternal(const String& error_message);
 
-  // Evaluate a script file in the current execution environment.
-  v8::Local<v8::Value> EvaluateInternal(const ScriptSourceCode&,
-                                        SanitizeScriptErrors,
-                                        V8CacheOptions);
   void DisposeContextIfNeeded();
 
   Member<WorkerOrWorkletGlobalScope> global_scope_;
@@ -134,14 +162,6 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
 
   scoped_refptr<RejectedPromises> rejected_promises_;
 
-  // |execution_state_| refers to a stack object that evaluate() allocates;
-  // evaluate() ensuring that the pointer reference to it is removed upon
-  // returning. Hence kept as a bare pointer here, and not a Persistent with
-  // Oilpan enabled; stack scanning will visit the object and
-  // trace its on-heap fields.
-  GC_PLUGIN_IGNORE("394615")
-  ExecutionState* execution_state_;
-
   DISALLOW_COPY_AND_ASSIGN(WorkerOrWorkletScriptController);
 };
 
diff --git a/third_party/blink/renderer/core/script/classic_script.cc b/third_party/blink/renderer/core/script/classic_script.cc
index 4141aad695f7f..17493fd1da1e4 100644
--- a/third_party/blink/renderer/core/script/classic_script.cc
+++ b/third_party/blink/renderer/core/script/classic_script.cc
@@ -57,10 +57,10 @@ bool ClassicScript::RunScriptOnWorkerOrWorklet(
   DCHECK(global_scope.IsContextThread());
 
   ScriptState::Scope scope(global_scope.ScriptController()->GetScriptState());
-  v8::Local<v8::Value> result =
+  ClassicEvaluationResult result =
       global_scope.ScriptController()->EvaluateAndReturnValue(
           GetScriptSourceCode(), sanitize_script_errors_,
-          nullptr /* error_event */, global_scope.GetV8CacheOptions());
+          global_scope.GetV8CacheOptions());
   return !result.IsEmpty();
 }
 
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
index 53a81c00c5498..d36918985a905 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/core/css/font_face_set_worker.h"
@@ -216,23 +217,42 @@ String WorkerGlobalScope::origin() const {
   return GetSecurityOrigin()->ToString();
 }
 
-void WorkerGlobalScope::importScripts(const Vector<String>& urls,
-                                      ExceptionState& exception_state) {
-  ImportScriptsInternal(urls, exception_state);
+void WorkerGlobalScope::importScripts(const Vector<String>& urls) {
+  ImportScriptsInternal(urls);
 }
 
+namespace {
+
+String NetworkErrorMessageAtImportScript(const char* const property_name,
+                                         const char* const interface_name,
+                                         const KURL& url) {
+  return ExceptionMessages::FailedToExecute(
+      property_name, interface_name,
+      "The script at '" + url.ElidedString() + "' failed to load.");
+}
+
+}  // namespace
+
 // Implementation of the "import scripts into worker global scope" algorithm:
 // https://html.spec.whatwg.org/C/#import-scripts-into-worker-global-scope
-void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
-                                              ExceptionState& exception_state) {
+void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls) {
   DCHECK(GetContentSecurityPolicy());
   DCHECK(GetExecutionContext());
+  v8::Isolate* isolate = GetThread()->GetIsolate();
+
+  // Previously, exceptions here were thrown via ExceptionState but now are
+  // thrown via V8ThrowException. To keep the existing error messages,
+  // ExceptionMessages::FailedToExecute() is called directly (crbug/1114610).
+  const char* const property_name = "importScripts";
+  const char* const interface_name = "WorkerGlobalScope";
 
   // Step 1: "If worker global scope's type is "module", throw a TypeError
   // exception."
   if (script_type_ == mojom::ScriptType::kModule) {
-    exception_state.ThrowTypeError(
-        "Module scripts don't support importScripts().");
+    V8ThrowException::ThrowTypeError(
+        isolate, ExceptionMessages::FailedToExecute(
+                     property_name, interface_name,
+                     "Module scripts don't support importScripts()."));
     return;
   }
 
@@ -249,17 +269,22 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
   for (const String& url_string : urls) {
     const KURL& url = CompleteURL(url_string);
     if (!url.IsValid()) {
-      exception_state.ThrowDOMException(
-          DOMExceptionCode::kSyntaxError,
-          "The URL '" + url_string + "' is invalid.");
+      V8ThrowException::ThrowException(
+          isolate, V8ThrowDOMException::CreateOrEmpty(
+                       isolate, DOMExceptionCode::kSyntaxError,
+                       ExceptionMessages::FailedToExecute(
+                           property_name, interface_name,
+                           "The URL '" + url_string + "' is invalid.")));
       return;
     }
     if (!GetContentSecurityPolicy()->AllowScriptFromSource(
             url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted,
             url, RedirectStatus::kNoRedirect)) {
-      exception_state.ThrowDOMException(
-          DOMExceptionCode::kNetworkError,
-          "The script at '" + url.ElidedString() + "' failed to load.");
+      V8ThrowException::ThrowException(
+          isolate, V8ThrowDOMException::CreateOrEmpty(
+                       isolate, DOMExceptionCode::kNetworkError,
+                       NetworkErrorMessageAtImportScript(property_name,
+                                                         interface_name, url)));
       return;
     }
     completed_urls.push_back(url);
@@ -270,6 +295,8 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
     KURL response_url;
     String source_code;
     std::unique_ptr<Vector<uint8_t>> cached_meta_data;
+    const String error_message = NetworkErrorMessageAtImportScript(
+        property_name, interface_name, complete_url);
 
     // Step 5.1: "Fetch a classic worker-imported script given url and settings
     // object, passing along any custom perform the fetch steps provided. If
@@ -280,10 +307,10 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
       // TODO(vogelheim): In case of certain types of failure - e.g. 'nosniff'
       // block - this ought to be a DOMExceptionCode::kSecurityError, but that
       // information presently gets lost on the way.
-      exception_state.ThrowDOMException(DOMExceptionCode::kNetworkError,
-                                        "The script at '" +
-                                            complete_url.ElidedString() +
-                                            "' failed to load.");
+      V8ThrowException::ThrowException(
+          isolate,
+          V8ThrowDOMException::CreateOrEmpty(
+              isolate, DOMExceptionCode::kNetworkError, error_message));
       return;
     }
 
@@ -297,24 +324,26 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
 
     // Step 5.2: "Run the classic script script, with the rethrow errors
     // argument set to true."
-    ErrorEvent* error_event = nullptr;
     SingleCachedMetadataHandler* handler(
         CreateWorkerScriptCachedMetadataHandler(complete_url,
                                                 std::move(cached_meta_data)));
     ReportingProxy().WillEvaluateImportedClassicScript(
         source_code.length(), handler ? handler->GetCodeCacheSize() : 0);
     ScriptState::Scope scope(ScriptController()->GetScriptState());
-    ScriptController()->EvaluateAndReturnValue(
+    ClassicEvaluationResult result = ScriptController()->EvaluateAndReturnValue(
         ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown,
                          handler,
                          ScriptSourceCode::UsePostRedirectURL() ? response_url
                                                                 : complete_url),
-        sanitize_script_errors, &error_event, GetV8CacheOptions());
-    if (error_event) {
-      ScriptController()->RethrowExceptionFromImportedScript(error_event,
-                                                             exception_state);
+        sanitize_script_errors, GetV8CacheOptions(),
+        WorkerOrWorkletScriptController::RethrowErrorsOption::Rethrow(
+            error_message));
+
+    // Step 5.2: "If an exception was thrown or if the script was prematurely
+    // aborted, then abort all these steps, letting the exception or aborting
+    // continue to be processed by the calling script."
+    if (result.IsEmpty())
       return;
-    }
   }
 }
 
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index e2f52c2d9ca4d..d4b5f097d1d24 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -52,7 +52,6 @@ namespace blink {
 
 struct BlinkTransferableMessage;
 class ConsoleMessage;
-class ExceptionState;
 class FetchClientSettingsObjectSnapshot;
 class FontFaceSet;
 class InstalledScriptsManager;
@@ -105,8 +104,9 @@ class CORE_EXPORT WorkerGlobalScope
   DEFINE_ATTRIBUTE_EVENT_LISTENER(timezonechange, kTimezonechange)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection)
 
-  // WorkerUtils
-  virtual void importScripts(const Vector<String>& urls, ExceptionState&);
+  // This doesn't take an ExceptionState argument, but actually can throw
+  // exceptions directly to V8 (crbug/1114610).
+  virtual void importScripts(const Vector<String>& urls);
 
   // ExecutionContext
   const KURL& Url() const final;
@@ -255,7 +255,7 @@ class CORE_EXPORT WorkerGlobalScope
   void RunWorkerScript();
 
   // Used for importScripts().
-  void ImportScriptsInternal(const Vector<String>& urls, ExceptionState&);
+  void ImportScriptsInternal(const Vector<String>& urls);
   // ExecutionContext
   void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) final;
   EventTarget* ErrorEventTarget() final { return this; }
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.idl b/third_party/blink/renderer/core/workers/worker_global_scope.idl
index a84f6fd89d66b..94fb4077d8603 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.idl
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.idl
@@ -41,7 +41,9 @@
     // attribute EventHandler ononline;
 
     // https://html.spec.whatwg.org/C/#apis-available-to-workers
-    [RaisesException] void importScripts(ScriptURLString... urls);
+    // Although RaisesException is not specified, importScripts() can actually
+    // throw exceptions directly to V8.
+    void importScripts(ScriptURLString... urls);
     readonly attribute WorkerNavigator navigator;
 
 
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
index 8c344748e5507..6c5c19aca1db0 100644
--- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
@@ -148,18 +148,27 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
     waitable_event->Signal();
   }
 
+  static bool RunScriptAndGetBoolean(AnimationWorkletGlobalScope* global_scope,
+                                     const String& script) {
+    ScriptState* script_state =
+        global_scope->ScriptController()->GetScriptState();
+    DCHECK(script_state);
+    v8::Isolate* isolate = script_state->GetIsolate();
+    DCHECK(isolate);
+    ScriptState::Scope scope(script_state);
+
+    ClassicEvaluationResult result =
+        global_scope->ScriptController()->EvaluateAndReturnValue(
+            ScriptSourceCode(script), SanitizeScriptErrors::kSanitize);
+    DCHECK(!result.IsEmpty());
+    return ToBoolean(isolate, result.GetValue(), ASSERT_NO_EXCEPTION);
+  }
+
   void RunConstructAndAnimateTestOnWorklet(
       WorkerThread* thread,
       base::WaitableEvent* waitable_event) {
     ASSERT_TRUE(thread->IsCurrentThread());
     auto* global_scope = To<AnimationWorkletGlobalScope>(thread->GlobalScope());
-    ScriptState* script_state =
-        global_scope->ScriptController()->GetScriptState();
-    ASSERT_TRUE(script_state);
-    v8::Isolate* isolate = script_state->GetIsolate();
-    ASSERT_TRUE(isolate);
-
-    ScriptState::Scope scope(script_state);
 
     String source_code =
         R"JS(
@@ -182,18 +191,12 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
         ClassicScript::CreateUnspecifiedScript(ScriptSourceCode(source_code))
             ->RunScriptOnWorkerOrWorklet(*global_scope));
 
-    v8::Local<v8::Value> constructed_before =
-        global_scope->ScriptController()->EvaluateAndReturnValue(
-            ScriptSourceCode("Function('return this')().constructed"),
-            SanitizeScriptErrors::kSanitize);
-    EXPECT_FALSE(ToBoolean(isolate, constructed_before, ASSERT_NO_EXCEPTION))
+    EXPECT_FALSE(RunScriptAndGetBoolean(
+        global_scope, "Function('return this')().constructed"))
         << "constructor is not invoked";
 
-    v8::Local<v8::Value> animated_before =
-        global_scope->ScriptController()->EvaluateAndReturnValue(
-            ScriptSourceCode("Function('return this')().animated"),
-            SanitizeScriptErrors::kSanitize);
-    EXPECT_FALSE(ToBoolean(isolate, animated_before, ASSERT_NO_EXCEPTION))
+    EXPECT_FALSE(RunScriptAndGetBoolean(global_scope,
+                                        "Function('return this')().animated"))
         << "animate function is invoked early";
 
     // Passing a new input state with a new animation id should cause the
@@ -209,18 +212,12 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
         ProxyClientMutate(state, global_scope);
     EXPECT_EQ(output->animations.size(), 1ul);
 
-    v8::Local<v8::Value> constructed_after =
-        global_scope->ScriptController()->EvaluateAndReturnValue(
-            ScriptSourceCode("Function('return this')().constructed"),
-            SanitizeScriptErrors::kSanitize);
-    EXPECT_TRUE(ToBoolean(isolate, constructed_after, ASSERT_NO_EXCEPTION))
+    EXPECT_TRUE(RunScriptAndGetBoolean(global_scope,
+                                       "Function('return this')().constructed"))
         << "constructor is not invoked";
 
-    v8::Local<v8::Value> animated_after =
-        global_scope->ScriptController()->EvaluateAndReturnValue(
-            ScriptSourceCode("Function('return this')().animated"),
-            SanitizeScriptErrors::kSanitize);
-    EXPECT_TRUE(ToBoolean(isolate, animated_after, ASSERT_NO_EXCEPTION))
+    EXPECT_TRUE(RunScriptAndGetBoolean(global_scope,
+                                       "Function('return this')().animated"))
         << "animate function is not invoked";
 
     waitable_event->Signal();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index ebfc413c22730..bd425f6f9b7da 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -55,6 +55,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_content_index_event_init.h"
@@ -825,22 +826,24 @@ int ServiceWorkerGlobalScope::GetOutstandingThrottledLimit() const {
   return features::kInstallingServiceWorkerOutstandingThrottledLimit.Get();
 }
 
-void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls,
-                                             ExceptionState& exception_state) {
+void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls) {
   for (const String& string_url : urls) {
     KURL completed_url = CompleteURL(string_url);
     if (installed_scripts_manager_ &&
         !installed_scripts_manager_->IsScriptInstalled(completed_url)) {
       DCHECK(installed_scripts_manager_->IsScriptInstalled(Url()));
-      exception_state.ThrowDOMException(
-          DOMExceptionCode::kNetworkError,
-          "Failed to import '" + completed_url.ElidedString() +
-              "'. importScripts() of new scripts after service worker "
-              "installation is not allowed.");
+      v8::Isolate* isolate = GetThread()->GetIsolate();
+      V8ThrowException::ThrowException(
+          isolate,
+          V8ThrowDOMException::CreateOrEmpty(
+              isolate, DOMExceptionCode::kNetworkError,
+              "Failed to import '" + completed_url.ElidedString() +
+                  "'. importScripts() of new scripts after service worker "
+                  "installation is not allowed."));
       return;
     }
   }
-  WorkerGlobalScope::importScripts(urls, exception_state);
+  WorkerGlobalScope::importScripts(urls);
 }
 
 SingleCachedMetadataHandler*
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index da50e108d743d..d5fd966d96e4b 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -339,7 +339,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
       const override;
 
  private:
-  void importScripts(const Vector<String>& urls, ExceptionState&) override;
+  void importScripts(const Vector<String>& urls) override;
   SingleCachedMetadataHandler* CreateWorkerScriptCachedMetadataHandler(
       const KURL& script_url,
       std::unique_ptr<Vector<uint8_t>> meta_data) override;
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-sharedworker-expected.txt
deleted file mode 100644
index 7ce88a522349e..0000000000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-sharedworker-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test evaluation order of modules assert_array_equals: expected property 2 to be "global-error" but got "microtask" (expected array ["step-1-1", "step-1-2", "global-error", "error", "microtask"] got ["step-1-1", "step-1-2", "microtask", "global-error", "error"])
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-worker-expected.txt
deleted file mode 100644
index 7ce88a522349e..0000000000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/evaluation-order-1-worker-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test evaluation order of modules assert_array_equals: expected property 2 to be "global-error" but got "microtask" (expected array ["step-1-1", "step-1-2", "global-error", "error", "microtask"] got ["step-1-1", "step-1-2", "microtask", "global-error", "error"])
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-expected.txt
deleted file mode 100644
index 40f3999e52611..0000000000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-workerglobalscope-onerror-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Promise resolved during #report-the-error assert_array_equals: expected property 1 to be "handler 2" but got "handler 1 promise" (expected array ["handler 1", "handler 2", "handler 1 promise", "handler 2 promise"] got ["handler 1", "handler 1 promise", "handler 2", "handler 2 promise"])
-PASS Promise resolved during event handlers other than error
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/wasm/jsapi/table/grow-reftypes.tentative.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/wasm/jsapi/table/grow-reftypes.tentative.any.worker-expected.txt
index 4354c6fb35392..7d6bf80291cd2 100644
--- a/third_party/blink/web_tests/external/wpt/wasm/jsapi/table/grow-reftypes.tentative.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/wasm/jsapi/table/grow-reftypes.tentative.any.worker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught 
+Harness Error. harness_status.status = 1 , harness_status.message = Uncaught NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://web-platform.test:8001/wasm/jsapi/wasm-constants.js' failed to load.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/quic/client-indication.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/quic/client-indication.sub.any.worker-expected.txt
index 4354c6fb35392..ef7377a17d731 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/quic/client-indication.sub.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webtransport/quic/client-indication.sub.any.worker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught 
+Harness Error. harness_status.status = 1 , harness_status.message = Uncaught NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://web-platform.test:8001/webtransport/quic/client-indication.sub.any.js' failed to load.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException-expected.txt
deleted file mode 100644
index 0743ef6504d1c..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL Throw DOMException-TypeError in toplevel: classic: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
-FAIL Throw DOMException-TypeError in toplevel: classic: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
-PASS Throw DOMException-TypeError in setTimeout-function: classic: listener
-PASS Throw DOMException-TypeError in setTimeout-function: classic: handler
-FAIL Throw DOMException-TypeError in setTimeout-string: classic: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
-FAIL Throw DOMException-TypeError in setTimeout-string: classic: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
-PASS Throw DOMException-TypeError in onmessage: classic: listener
-PASS Throw DOMException-TypeError in onmessage: classic: handler
-PASS Throw DOMException-TypeError in onerror: classic: listener
-PASS Throw DOMException-TypeError in onerror: classic: handler
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException-expected.txt
index d1238f95e07bc..00118cc8651ef 100644
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException-expected.txt
@@ -3,8 +3,8 @@ FAIL Throw DOMException-TypeError in toplevel: module: listener assert_regexp_ma
 FAIL Throw DOMException-TypeError in toplevel: module: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
 PASS Throw DOMException-TypeError in setTimeout-function: module: listener
 PASS Throw DOMException-TypeError in setTimeout-function: module: handler
-FAIL Throw DOMException-TypeError in setTimeout-string: module: listener assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
-FAIL Throw DOMException-TypeError in setTimeout-string: module: handler assert_regexp_match: e.message should contain the message of the thrown error expected object "/Throw in/" but got "Uncaught "
+PASS Throw DOMException-TypeError in setTimeout-string: module: listener
+PASS Throw DOMException-TypeError in setTimeout-string: module: handler
 PASS Throw DOMException-TypeError in onmessage: module: listener
 PASS Throw DOMException-TypeError in onmessage: module: handler
 PASS Throw DOMException-TypeError in onerror: module: listener
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt
deleted file mode 100644
index 32ebda0c8b37e..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.serviceworker-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-PASS Same-origin syntax error
-PASS Same-origin throw
-FAIL Cross-origin syntax error assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/syntax-error.js");
-  }" threw null, not an object
-FAIL Cross-origin throw assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/throw.js");
-  }" threw null, not an object
-PASS Redirect-to-cross-origin syntax error
-PASS Redirect-to-Cross-origin throw
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt
deleted file mode 100644
index 1942e64d2b3db..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Same-origin syntax error
-PASS Same-origin throw
-FAIL Cross-origin syntax error assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/syntax-error.js");
-  }" threw null, not an object
-FAIL Cross-origin throw assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/throw.js");
-  }" threw null, not an object
-FAIL Redirect-to-cross-origin syntax error assert_throws_dom: function "function() {
-    importScripts(redirectToCrossOrigin +
-                  "/workers/modules/resources/syntax-error.js");
-  }" threw null, not an object
-FAIL Redirect-to-Cross-origin throw assert_throws_dom: function "function() {
-    importScripts(redirectToCrossOrigin +
-                  "/workers/modules/resources/throw.js");
-  }" threw null, not an object
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt
deleted file mode 100644
index 1942e64d2b3db..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS Same-origin syntax error
-PASS Same-origin throw
-FAIL Cross-origin syntax error assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/syntax-error.js");
-  }" threw null, not an object
-FAIL Cross-origin throw assert_throws_dom: function "function() {
-    importScripts(crossOrigin +
-                  "/workers/modules/resources/throw.js");
-  }" threw null, not an object
-FAIL Redirect-to-cross-origin syntax error assert_throws_dom: function "function() {
-    importScripts(redirectToCrossOrigin +
-                  "/workers/modules/resources/syntax-error.js");
-  }" threw null, not an object
-FAIL Redirect-to-Cross-origin throw assert_throws_dom: function "function() {
-    importScripts(redirectToCrossOrigin +
-                  "/workers/modules/resources/throw.js");
-  }" threw null, not an object
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt
deleted file mode 100644
index db4107573033f..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt
deleted file mode 100644
index db4107573033f..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
deleted file mode 100644
index db4107573033f..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt
deleted file mode 100644
index db4107573033f..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-FAIL WorkerGlobalScope error event: message assert_not_equals: e.message should not be muted to 'Script error.' got disallowed value "Script error."
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js" but got ""
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 8 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt
deleted file mode 100644
index 81bc6acab7090..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-PASS WorkerGlobalScope error event: message
-PASS WorkerGlobalScope error event: filename
-PASS WorkerGlobalScope error event: lineno
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt
deleted file mode 100644
index 81bc6acab7090..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-PASS WorkerGlobalScope error event: message
-PASS WorkerGlobalScope error event: filename
-PASS WorkerGlobalScope error event: lineno
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
deleted file mode 100644
index 81bc6acab7090..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-PASS WorkerGlobalScope error event: message
-PASS WorkerGlobalScope error event: filename
-PASS WorkerGlobalScope error event: lineno
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt
deleted file mode 100644
index 81bc6acab7090..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL WorkerGlobalScope error event: error Cannot read property 'constructor' of null
-PASS WorkerGlobalScope error event: message
-PASS WorkerGlobalScope error event: filename
-PASS WorkerGlobalScope error event: lineno
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt
deleted file mode 100644
index 736c8c65d74da..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.sharedworker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS WorkerGlobalScope error event: error
-PASS WorkerGlobalScope error event: message
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/modules/resources/syntax-error.js" but got "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js"
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 1 but got 8
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt
deleted file mode 100644
index 736c8c65d74da..0000000000000
--- a/third_party/blink/web_tests/external/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.worker-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS WorkerGlobalScope error event: error
-PASS WorkerGlobalScope error event: message
-FAIL WorkerGlobalScope error event: filename assert_equals: expected "http://web-platform.test:8001/workers/modules/resources/syntax-error.js" but got "http://web-platform.test:8001/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js"
-FAIL WorkerGlobalScope error event: lineno assert_equals: expected 1 but got 8
-Harness: the test ran to completion.
-