Skip to content

Commit fedf93e

Browse files
authored
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
1 parent b1d9ffa commit fedf93e

File tree

7 files changed

+39
-14
lines changed

7 files changed

+39
-14
lines changed

.changes/refactor-ipc-error.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:changes
3+
---
4+
5+
Change how IPC handles errors to simplify what's logged in the console.

core/tauri/scripts/ipc-protocol.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
}
4343
})
4444
.then((response) => {
45-
const cb = response.ok ? callback : error
45+
const cb =
46+
response.headers.get('Tauri-Response') === 'ok' ? callback : error
4647
// we need to split here because on Android the content-type gets duplicated
4748
switch ((response.headers.get('content-type') || '').split(',')[0]) {
4849
case 'application/json':

core/tauri/src/ipc/protocol.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use crate::{
1010
Runtime,
1111
};
1212
use http::{
13-
header::{ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE},
13+
header::{
14+
ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS,
15+
CONTENT_TYPE,
16+
},
1417
HeaderValue, Method, Request, StatusCode,
1518
};
1619
use url::Url;
@@ -21,6 +24,10 @@ const TAURI_CALLBACK_HEADER_NAME: &str = "Tauri-Callback";
2124
const TAURI_ERROR_HEADER_NAME: &str = "Tauri-Error";
2225
const TAURI_INVOKE_KEY_HEADER_NAME: &str = "Tauri-Invoke-Key";
2326

27+
const TAURI_RESPONSE_HEADER_NAME: &str = "Tauri-Response";
28+
const TAURI_RESPONSE_HEADER_ERROR: &str = "error";
29+
const TAURI_RESPONSE_HEADER_OK: &str = "ok";
30+
2431
pub fn message_handler<R: Runtime>(
2532
manager: Arc<AppManager<R>>,
2633
) -> crate::runtime::webview::WebviewIpcHandler<crate::EventLoopMessage, R> {
@@ -44,6 +51,10 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
4451
response
4552
.headers_mut()
4653
.insert(ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
54+
response.headers_mut().insert(
55+
ACCESS_CONTROL_EXPOSE_HEADERS,
56+
HeaderValue::from_static(TAURI_RESPONSE_HEADER_NAME),
57+
);
4758
responder.respond(response);
4859
};
4960

@@ -81,6 +92,11 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
8192
)
8293
.entered();
8394

95+
let response_header = match &response {
96+
InvokeResponse::Ok(_) => TAURI_RESPONSE_HEADER_OK,
97+
InvokeResponse::Err(_) => TAURI_RESPONSE_HEADER_ERROR,
98+
};
99+
84100
let (mut response, mime_type) = match response {
85101
InvokeResponse::Ok(InvokeBody::Json(v)) => (
86102
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
90106
http::Response::new(v.into()),
91107
mime::APPLICATION_OCTET_STREAM,
92108
),
93-
InvokeResponse::Err(e) => {
94-
let mut response =
95-
http::Response::new(serde_json::to_vec(&e.0).unwrap().into());
96-
*response.status_mut() = StatusCode::BAD_REQUEST;
97-
(response, mime::APPLICATION_JSON)
98-
}
109+
InvokeResponse::Err(e) => (
110+
http::Response::new(serde_json::to_vec(&e.0).unwrap().into()),
111+
mime::APPLICATION_JSON,
112+
),
99113
};
100114

115+
response
116+
.headers_mut()
117+
.insert(TAURI_RESPONSE_HEADER_NAME, response_header.parse().unwrap());
118+
101119
#[cfg(feature = "tracing")]
102120
response_span.record("mime_type", mime_type.essence_str());
103121

@@ -113,7 +131,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
113131
Err(e) => {
114132
respond(
115133
http::Response::builder()
116-
.status(StatusCode::BAD_REQUEST)
134+
.status(StatusCode::INTERNAL_SERVER_ERROR)
117135
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
118136
.body(e.as_bytes().to_vec().into())
119137
.unwrap(),
@@ -123,7 +141,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
123141
} else {
124142
respond(
125143
http::Response::builder()
126-
.status(StatusCode::BAD_REQUEST)
144+
.status(StatusCode::INTERNAL_SERVER_ERROR)
127145
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
128146
.body(
129147
"failed to acquire webview reference"
@@ -140,6 +158,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
140158
let mut r = http::Response::new(Vec::new().into());
141159
r.headers_mut()
142160
.insert(ACCESS_CONTROL_ALLOW_HEADERS, HeaderValue::from_static("*"));
161+
143162
respond(r);
144163
}
145164

core/tauri/src/protocol/asset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn get(scope: scope::fs::Scope, window_origin: String) -> UriSchemeProtocolH
1616
Ok(response) => responder.respond(response),
1717
Err(e) => responder.respond(
1818
http::Response::builder()
19-
.status(http::StatusCode::BAD_REQUEST)
19+
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
2020
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
2121
.header("Access-Control-Allow-Origin", &window_origin)
2222
.body(e.to_string().as_bytes().to_vec())

core/tauri/src/protocol/isolation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn get<R: Runtime>(
7777
} else {
7878
responder.respond(
7979
http::Response::builder()
80-
.status(http::StatusCode::BAD_REQUEST)
80+
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
8181
.body("failed to get response".as_bytes().to_vec())
8282
.unwrap(),
8383
);

core/tauri/src/protocol/tauri.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn get<R: Runtime>(
5454
Ok(response) => responder.respond(response),
5555
Err(e) => responder.respond(
5656
HttpResponse::builder()
57-
.status(StatusCode::BAD_REQUEST)
57+
.status(StatusCode::INTERNAL_SERVER_ERROR)
5858
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
5959
.header("Access-Control-Allow-Origin", &window_origin)
6060
.body(e.to_string().as_bytes().to_vec())

examples/streaming/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn main() {
4242
Ok(http_response) => responder.respond(http_response),
4343
Err(e) => responder.respond(
4444
ResponseBuilder::new()
45-
.status(StatusCode::BAD_REQUEST)
45+
.status(StatusCode::INTERNAL_SERVER_ERROR)
4646
.header(CONTENT_TYPE, "text/plain")
4747
.body(e.to_string().as_bytes().to_vec())
4848
.unwrap(),

0 commit comments

Comments
 (0)