Add trace events in WebRequestProxyingURLLoaderFactory

These would be useful to investigate how webRequest APIs could cancel
requests.

Bug: 1213400
Change-Id: Idddb8ed0aebd721ace88f7e81b91217c9c06ca23
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3029305
Reviewed-by: ssid <[email protected]>
Reviewed-by: Yutaka Hirano <[email protected]>
Reviewed-by: Karan Bhatia <[email protected]>
Commit-Queue: Kenichi Ishibashi <[email protected]>
Cr-Commit-Position: refs/heads/master@{#902248}
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index a9616406d..96624924 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -80,6 +80,7 @@
   X("evdev")                                                             \
   X("event")                                                             \
   X("exo")                                                               \
+  X("extensions")                                                        \
   X("explore_sites")                                                     \
   X("FileSystem")                                                        \
   X("file_system_provider")                                              \
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index 1e15e033..b5abd5ce 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -26,6 +26,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
 #include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
 #include "base/values.h"
 #include "components/ukm/content/source_url_recorder.h"
 #include "content/public/browser/browser_context.h"
@@ -182,6 +183,7 @@
   DCHECK_NE(RequestAction::MAX, action);
   UMA_HISTOGRAM_ENUMERATION("Extensions.WebRequestAction", action,
                             RequestAction::MAX);
+  TRACE_EVENT1("extensions", "WebRequestAction", "action", action);
 }
 
 // Returns the corresponding EventTypes for the given |event_name|. If
@@ -2327,6 +2329,8 @@
     rv = net::ERR_BLOCKED_BY_CLIENT;
     RecordNetworkRequestBlocked(request->ukm_source_id,
                                 canceled_by_extension.value());
+    TRACE_EVENT2("extensions", "NetworkRequestBlockedByClient", "extension",
+                 canceled_by_extension.value(), "id", request->id);
   }
 
   if (!blocked_request.callback.is_null()) {
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h
index c68c1830..11408b995 100644
--- a/extensions/browser/api/web_request/web_request_api.h
+++ b/extensions/browser/api/web_request/web_request_api.h
@@ -670,11 +670,11 @@
                            int extra_info_spec);
 
   // Processes the generated deltas from blocked_requests_ on the specified
-  // request. If |call_back| is true, the callback registered in
+  // request. If |call_callback| is true, the callback registered in
   // |blocked_requests_| is called.
   // The function returns the error code for the network request. This is
   // mostly relevant in case the caller passes |call_callback| = false
-  // and wants to return the correct network error code himself.
+  // and wants to return the correct network error code themself.
   int ExecuteDeltas(content::BrowserContext* browser_context,
                     const WebRequestInfo* request,
                     bool call_callback);
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index 15025d5..48f8e0e 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
+#include "base/trace_event/trace_event.h"
 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
 #include "components/ukm/content/source_url_recorder.h"
 #include "content/public/browser/browser_context.h"
@@ -50,6 +51,11 @@
 namespace extensions {
 namespace {
 
+// TODO(crbug.com/1213400): Consider removing traces when the cause of the issue
+// is identified.
+constexpr char kWebRequestProxyingURLLoaderFactoryScope[] =
+    "WebRequestProxyingURLLoaderFactory";
+
 // This shutdown notifier makes sure the proxy is destroyed if an incognito
 // browser context is destroyed. This is needed because WebRequestAPI only
 // clears the proxies when the original browser context is destroyed.
@@ -129,6 +135,14 @@
           network_service_request_id_ != 0 &&
           ExtensionWebRequestEventRouter::GetInstance()
               ->HasAnyExtraHeadersListener(factory_->browser_context_)) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "InProgressRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_OUT, "url", request.url.spec());
+
   // If there is a client error, clean up the request.
   target_client_.set_disconnect_handler(
       base::BindOnce(&WebRequestProxyingURLLoaderFactory::InProgressRequest::
@@ -155,10 +169,27 @@
       for_cors_preflight_(true),
       has_any_extra_headers_listeners_(
           ExtensionWebRequestEventRouter::GetInstance()
-              ->HasAnyExtraHeadersListener(factory_->browser_context_)) {}
+              ->HasAnyExtraHeadersListener(factory_->browser_context_)) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "InProgressRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_OUT, "url", request.url.spec());
+}
 
 WebRequestProxyingURLLoaderFactory::InProgressRequest::~InProgressRequest() {
   DCHECK_NE(state_, State::kInvalid);
+
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "~InProgressRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN, "state", state_);
+
   if (request_.keepalive && !for_cors_preflight_) {
     UMA_HISTOGRAM_ENUMERATION("Extensions.WebRequest.KeepaliveRequestState",
                               state_);
@@ -350,6 +381,14 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnReceiveResponse",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (current_request_uses_header_client_) {
     // Use the headers we got from OnHeadersReceived as that'll contain
     // Set-Cookie if it existed.
@@ -368,6 +407,14 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnReceiveRedirect(
     const net::RedirectInfo& redirect_info,
     network::mojom::URLResponseHeadPtr head) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnReceiveRedirect",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (redirect_url_ != redirect_info.new_url &&
       !IsRedirectSafe(request_.url, redirect_info.new_url,
                       info_->is_navigation_request)) {
@@ -414,11 +461,28 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnStartLoadingResponseBody",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   target_client_->OnStartLoadingResponseBody(std::move(body));
 }
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnComplete(
     const network::URLLoaderCompletionStatus& status) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnComplete",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      status.error_code, "extended_error_code", status.extended_error_code);
+
   if (status.error_code != net::OK) {
     OnNetworkError(status);
     return;
@@ -439,6 +503,14 @@
     WebRequestAPI::AuthRequestCallback callback) {
   DCHECK(!auth_credentials_);
 
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "HandleAuthRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   // If |current_request_uses_header_client_| is true, |current_response_|
   // should already hold the correct set of response headers (including
   // Set-Cookie). So we don't use |response_headers| since it won't have the
@@ -466,6 +538,15 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnLoaderCreated(
     mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnLoaderCreated",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+      "for_cors_preflight", for_cors_preflight_);
+
   // When CORS is involved there may be multiple network::URLLoader associated
   // with this InProgressRequest, because CorsURLLoader may create a new
   // network::URLLoader for the same request id in redirect handling - see
@@ -491,6 +572,14 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnBeforeSendHeaders(
     const net::HttpRequestHeaders& headers,
     OnBeforeSendHeadersCallback callback) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnBeforeSendHeaders",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (!current_request_uses_header_client_) {
     std::move(callback).Run(net::OK, absl::nullopt);
     return;
@@ -505,6 +594,15 @@
     const std::string& headers,
     const net::IPEndPoint& remote_endpoint,
     OnHeadersReceivedCallback callback) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnHeadersReceived",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+      "for_cors_preflight", for_cors_preflight_);
+
   if (!current_request_uses_header_client_) {
     std::move(callback).Run(net::OK, absl::nullopt, absl::nullopt);
 
@@ -528,6 +626,14 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     HandleBeforeRequestRedirect() {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "HandleBeforeRequestRedirect",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   // The extension requested a redirect. Close the connection with the current
   // URLLoader and inform the URLLoaderClient the WebRequest API generated a
   // redirect. To load |redirect_url_|, a new URLLoader will be recreated
@@ -578,6 +684,15 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     ContinueToBeforeSendHeaders(State state_on_error, int error_code) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToBeforeSendHeaders",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "state_on_error",
+      state_on_error, "error_code", error_code);
+
   if (error_code != net::OK) {
     OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
     return;
@@ -606,6 +721,14 @@
             factory_->browser_context_, &info_.value(), continuation,
             &request_.headers);
 
+    TRACE_EVENT_WITH_FLOW1(
+        "extensions",
+        "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+        "OnBeforeSendHeaders",
+        TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                            TRACE_ID_LOCAL(request_id_)),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result);
+
     if (result == net::ERR_BLOCKED_BY_CLIENT) {
       // The request was cancelled synchronously. Dispatch an error notification
       // and terminate the request.
@@ -635,6 +758,15 @@
 }
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     ContinueToStartRequest(State state_on_error, int error_code) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToStartRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "state_on_error",
+      state_on_error, "error_code", error_code);
+
   if (error_code != net::OK) {
     OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
     return;
@@ -696,6 +828,15 @@
                           const std::set<std::string>& removed_headers,
                           const std::set<std::string>& set_headers,
                           int error_code) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToSendHeaders",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "state_on_error",
+      state_on_error, "error_code", error_code);
+
   if (error_code != net::OK) {
     OnRequestError(CreateURLLoaderCompletionStatus(error_code), state_on_error);
     return;
@@ -757,6 +898,15 @@
     const net::AuthChallengeInfo& auth_info,
     WebRequestAPI::AuthRequestCallback callback,
     int error_code) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueAuthRequest",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      error_code);
+
   if (error_code != net::OK) {
     // Here we come from an onHeaderReceived failure.
     state_ = State::kRejectedByOnHeadersReceivedForAuth;
@@ -796,6 +946,15 @@
     OnAuthRequestHandled(
         WebRequestAPI::AuthRequestCallback callback,
         ExtensionWebRequestEventRouter::AuthRequiredResponse response) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnAuthRequestHandled",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "response",
+      response);
+
   if (proxied_client_receiver_.is_bound())
     proxied_client_receiver_.Resume();
 
@@ -832,6 +991,15 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     ContinueToHandleOverrideHeaders(int error_code) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToHandleOverrideHeaders",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      error_code);
+
   if (error_code != net::OK) {
     const int status_code = current_response_->headers
                                 ? current_response_->headers->response_code()
@@ -894,6 +1062,16 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     OverwriteHeadersAndContinueToResponseStarted(int error_code) {
   DCHECK(!for_cors_preflight_);
+
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OverwriteHeadersAndContinueToResponseStarted",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      error_code, "loader_factory_type", factory_->loader_factory_type());
+
   if (error_code != net::OK) {
     OnRequestError(CreateURLLoaderCompletionStatus(error_code),
                    State::kRejectedByOnHeadersReceivedForFinalResponse);
@@ -945,12 +1123,28 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     AssignParsedHeadersAndContinueToResponseStarted(
         network::mojom::ParsedHeadersPtr parsed_headers) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "AssignParsedHeadersAndContinueToResponseStarted",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   current_response_->parsed_headers = std::move(parsed_headers);
   ContinueToResponseStarted();
 }
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     ContinueToResponseStarted() {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToResponseStarted",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (state_ == State::kInProgress) {
     state_ = State::kInProgressWithFinalResponseReceived;
   }
@@ -993,6 +1187,15 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     ContinueToBeforeRedirect(const net::RedirectInfo& redirect_info,
                              int error_code) {
+  TRACE_EVENT_WITH_FLOW1(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "ContinueToBeforeRedirect",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      error_code);
+
   if (error_code != net::OK) {
     OnRequestError(CreateURLLoaderCompletionStatus(error_code),
                    kRejectedByOnHeadersReceivedForRedirect);
@@ -1026,6 +1229,14 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::
     HandleResponseOrRedirectHeaders(net::CompletionOnceCallback continuation) {
+  TRACE_EVENT_WITH_FLOW0(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "HandleResponseOrRedirectHeaders",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   override_headers_ = nullptr;
   redirect_url_ = GURL();
 
@@ -1076,6 +1287,15 @@
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnRequestError(
     const network::URLLoaderCompletionStatus& status,
     State state) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnRequestError",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      status.error_code, "state", state);
+
   if (target_client_)
     target_client_->OnComplete(status);
   ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
@@ -1089,6 +1309,15 @@
 
 void WebRequestProxyingURLLoaderFactory::InProgressRequest::OnNetworkError(
     const network::URLLoaderCompletionStatus& status) {
+  TRACE_EVENT_WITH_FLOW2(
+      "extensions",
+      "WebRequestProxyingURLLoaderFactory::InProgressRequest::"
+      "OnNetworkError",
+      TRACE_ID_WITH_SCOPE(kWebRequestProxyingURLLoaderFactoryScope,
+                          TRACE_ID_LOCAL(request_id_)),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
+      status.error_code, "state", state_);
+
   State state = state_;
   if (state_ == State::kInProgress) {
     state = State::kRejectedByNetworkError;