Procházet zdrojové kódy

refactor(core): return 200 on any IPC call, closes #10286 (#10585)

* refactor(core): return 200 on any IPC call, closes #10286

By default the webview prints a `Failed to load resource: the server responded with a status of 400 (Bad Request) ipc://localhost` error message when a command returns an error, which is confusing to users.

This changes the IPC to return status 200 on any call, with a header to indicate whether the result was ok or not. This removes the console error, which would only log the actual error result if it isn't caught by the user.

* add change file

* apply code review changes
Lucas Fernandes Nogueira před 11 měsíci
rodič
revize
fedf93eb7e

+ 5 - 0
.changes/refactor-ipc-error.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch:changes
+---
+
+Change how IPC handles errors to simplify what's logged in the console.

+ 2 - 1
core/tauri/scripts/ipc-protocol.js

@@ -42,7 +42,8 @@
         }
       })
         .then((response) => {
-          const cb = response.ok ? callback : error
+          const cb =
+            response.headers.get('Tauri-Response') === 'ok' ? callback : error
           // we need to split here because on Android the content-type gets duplicated
           switch ((response.headers.get('content-type') || '').split(',')[0]) {
             case 'application/json':

+ 28 - 9
core/tauri/src/ipc/protocol.rs

@@ -10,7 +10,10 @@ use crate::{
   Runtime,
 };
 use http::{
-  header::{ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE},
+  header::{
+    ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS,
+    CONTENT_TYPE,
+  },
   HeaderValue, Method, Request, StatusCode,
 };
 use url::Url;
@@ -21,6 +24,10 @@ const TAURI_CALLBACK_HEADER_NAME: &str = "Tauri-Callback";
 const TAURI_ERROR_HEADER_NAME: &str = "Tauri-Error";
 const TAURI_INVOKE_KEY_HEADER_NAME: &str = "Tauri-Invoke-Key";
 
+const TAURI_RESPONSE_HEADER_NAME: &str = "Tauri-Response";
+const TAURI_RESPONSE_HEADER_ERROR: &str = "error";
+const TAURI_RESPONSE_HEADER_OK: &str = "ok";
+
 pub fn message_handler<R: Runtime>(
   manager: Arc<AppManager<R>>,
 ) -> crate::runtime::webview::WebviewIpcHandler<crate::EventLoopMessage, R> {
@@ -44,6 +51,10 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
       response
         .headers_mut()
         .insert(ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
+      response.headers_mut().insert(
+        ACCESS_CONTROL_EXPOSE_HEADERS,
+        HeaderValue::from_static(TAURI_RESPONSE_HEADER_NAME),
+      );
       responder.respond(response);
     };
 
@@ -81,6 +92,11 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
                   )
                   .entered();
 
+                  let response_header = match &response {
+                    InvokeResponse::Ok(_) => TAURI_RESPONSE_HEADER_OK,
+                    InvokeResponse::Err(_) => TAURI_RESPONSE_HEADER_ERROR,
+                  };
+
                   let (mut response, mime_type) = match response {
                     InvokeResponse::Ok(InvokeBody::Json(v)) => (
                       http::Response::new(serde_json::to_vec(&v).unwrap().into()),
@@ -90,14 +106,16 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
                       http::Response::new(v.into()),
                       mime::APPLICATION_OCTET_STREAM,
                     ),
-                    InvokeResponse::Err(e) => {
-                      let mut response =
-                        http::Response::new(serde_json::to_vec(&e.0).unwrap().into());
-                      *response.status_mut() = StatusCode::BAD_REQUEST;
-                      (response, mime::APPLICATION_JSON)
-                    }
+                    InvokeResponse::Err(e) => (
+                      http::Response::new(serde_json::to_vec(&e.0).unwrap().into()),
+                      mime::APPLICATION_JSON,
+                    ),
                   };
 
+                  response
+                    .headers_mut()
+                    .insert(TAURI_RESPONSE_HEADER_NAME, response_header.parse().unwrap());
+
                   #[cfg(feature = "tracing")]
                   response_span.record("mime_type", mime_type.essence_str());
 
@@ -113,7 +131,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
             Err(e) => {
               respond(
                 http::Response::builder()
-                  .status(StatusCode::BAD_REQUEST)
+                  .status(StatusCode::INTERNAL_SERVER_ERROR)
                   .header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
                   .body(e.as_bytes().to_vec().into())
                   .unwrap(),
@@ -123,7 +141,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
         } else {
           respond(
             http::Response::builder()
-              .status(StatusCode::BAD_REQUEST)
+              .status(StatusCode::INTERNAL_SERVER_ERROR)
               .header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
               .body(
                 "failed to acquire webview reference"
@@ -140,6 +158,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
         let mut r = http::Response::new(Vec::new().into());
         r.headers_mut()
           .insert(ACCESS_CONTROL_ALLOW_HEADERS, HeaderValue::from_static("*"));
+
         respond(r);
       }
 

+ 1 - 1
core/tauri/src/protocol/asset.rs

@@ -16,7 +16,7 @@ pub fn get(scope: scope::fs::Scope, window_origin: String) -> UriSchemeProtocolH
       Ok(response) => responder.respond(response),
       Err(e) => responder.respond(
         http::Response::builder()
-          .status(http::StatusCode::BAD_REQUEST)
+          .status(http::StatusCode::INTERNAL_SERVER_ERROR)
           .header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
           .header("Access-Control-Allow-Origin", &window_origin)
           .body(e.to_string().as_bytes().to_vec())

+ 1 - 1
core/tauri/src/protocol/isolation.rs

@@ -77,7 +77,7 @@ pub fn get<R: Runtime>(
     } else {
       responder.respond(
         http::Response::builder()
-          .status(http::StatusCode::BAD_REQUEST)
+          .status(http::StatusCode::INTERNAL_SERVER_ERROR)
           .body("failed to get response".as_bytes().to_vec())
           .unwrap(),
       );

+ 1 - 1
core/tauri/src/protocol/tauri.rs

@@ -54,7 +54,7 @@ pub fn get<R: Runtime>(
       Ok(response) => responder.respond(response),
       Err(e) => responder.respond(
         HttpResponse::builder()
-          .status(StatusCode::BAD_REQUEST)
+          .status(StatusCode::INTERNAL_SERVER_ERROR)
           .header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
           .header("Access-Control-Allow-Origin", &window_origin)
           .body(e.to_string().as_bytes().to_vec())

+ 1 - 1
examples/streaming/main.rs

@@ -42,7 +42,7 @@ fn main() {
         Ok(http_response) => responder.respond(http_response),
         Err(e) => responder.respond(
           ResponseBuilder::new()
-            .status(StatusCode::BAD_REQUEST)
+            .status(StatusCode::INTERNAL_SERVER_ERROR)
             .header(CONTENT_TYPE, "text/plain")
             .body(e.to_string().as_bytes().to_vec())
             .unwrap(),