mirror of https://github.com/tauri-apps/tauri
* 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
This commit is contained in:
parent
b1d9ffa1ab
commit
fedf93eb7e
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"tauri": patch:changes
|
||||||
|
---
|
||||||
|
|
||||||
|
Change how IPC handles errors to simplify what's logged in the console.
|
|
@ -42,7 +42,8 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.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
|
// we need to split here because on Android the content-type gets duplicated
|
||||||
switch ((response.headers.get('content-type') || '').split(',')[0]) {
|
switch ((response.headers.get('content-type') || '').split(',')[0]) {
|
||||||
case 'application/json':
|
case 'application/json':
|
||||||
|
|
|
@ -10,7 +10,10 @@ use crate::{
|
||||||
Runtime,
|
Runtime,
|
||||||
};
|
};
|
||||||
use http::{
|
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,
|
HeaderValue, Method, Request, StatusCode,
|
||||||
};
|
};
|
||||||
use url::Url;
|
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_ERROR_HEADER_NAME: &str = "Tauri-Error";
|
||||||
const TAURI_INVOKE_KEY_HEADER_NAME: &str = "Tauri-Invoke-Key";
|
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>(
|
pub fn message_handler<R: Runtime>(
|
||||||
manager: Arc<AppManager<R>>,
|
manager: Arc<AppManager<R>>,
|
||||||
) -> crate::runtime::webview::WebviewIpcHandler<crate::EventLoopMessage, 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
|
response
|
||||||
.headers_mut()
|
.headers_mut()
|
||||||
.insert(ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
|
.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);
|
responder.respond(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +92,11 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
|
||||||
)
|
)
|
||||||
.entered();
|
.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 {
|
let (mut response, mime_type) = match response {
|
||||||
InvokeResponse::Ok(InvokeBody::Json(v)) => (
|
InvokeResponse::Ok(InvokeBody::Json(v)) => (
|
||||||
http::Response::new(serde_json::to_vec(&v).unwrap().into()),
|
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()),
|
http::Response::new(v.into()),
|
||||||
mime::APPLICATION_OCTET_STREAM,
|
mime::APPLICATION_OCTET_STREAM,
|
||||||
),
|
),
|
||||||
InvokeResponse::Err(e) => {
|
InvokeResponse::Err(e) => (
|
||||||
let mut response =
|
http::Response::new(serde_json::to_vec(&e.0).unwrap().into()),
|
||||||
http::Response::new(serde_json::to_vec(&e.0).unwrap().into());
|
mime::APPLICATION_JSON,
|
||||||
*response.status_mut() = StatusCode::BAD_REQUEST;
|
),
|
||||||
(response, mime::APPLICATION_JSON)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
response
|
||||||
|
.headers_mut()
|
||||||
|
.insert(TAURI_RESPONSE_HEADER_NAME, response_header.parse().unwrap());
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
response_span.record("mime_type", mime_type.essence_str());
|
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) => {
|
Err(e) => {
|
||||||
respond(
|
respond(
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(StatusCode::BAD_REQUEST)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
||||||
.body(e.as_bytes().to_vec().into())
|
.body(e.as_bytes().to_vec().into())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
@ -123,7 +141,7 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
|
||||||
} else {
|
} else {
|
||||||
respond(
|
respond(
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(StatusCode::BAD_REQUEST)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
||||||
.body(
|
.body(
|
||||||
"failed to acquire webview reference"
|
"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());
|
let mut r = http::Response::new(Vec::new().into());
|
||||||
r.headers_mut()
|
r.headers_mut()
|
||||||
.insert(ACCESS_CONTROL_ALLOW_HEADERS, HeaderValue::from_static("*"));
|
.insert(ACCESS_CONTROL_ALLOW_HEADERS, HeaderValue::from_static("*"));
|
||||||
|
|
||||||
respond(r);
|
respond(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn get(scope: scope::fs::Scope, window_origin: String) -> UriSchemeProtocolH
|
||||||
Ok(response) => responder.respond(response),
|
Ok(response) => responder.respond(response),
|
||||||
Err(e) => responder.respond(
|
Err(e) => responder.respond(
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(http::StatusCode::BAD_REQUEST)
|
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
||||||
.header("Access-Control-Allow-Origin", &window_origin)
|
.header("Access-Control-Allow-Origin", &window_origin)
|
||||||
.body(e.to_string().as_bytes().to_vec())
|
.body(e.to_string().as_bytes().to_vec())
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub fn get<R: Runtime>(
|
||||||
} else {
|
} else {
|
||||||
responder.respond(
|
responder.respond(
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(http::StatusCode::BAD_REQUEST)
|
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.body("failed to get response".as_bytes().to_vec())
|
.body("failed to get response".as_bytes().to_vec())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -54,7 +54,7 @@ pub fn get<R: Runtime>(
|
||||||
Ok(response) => responder.respond(response),
|
Ok(response) => responder.respond(response),
|
||||||
Err(e) => responder.respond(
|
Err(e) => responder.respond(
|
||||||
HttpResponse::builder()
|
HttpResponse::builder()
|
||||||
.status(StatusCode::BAD_REQUEST)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
.header(CONTENT_TYPE, mime::TEXT_PLAIN.essence_str())
|
||||||
.header("Access-Control-Allow-Origin", &window_origin)
|
.header("Access-Control-Allow-Origin", &window_origin)
|
||||||
.body(e.to_string().as_bytes().to_vec())
|
.body(e.to_string().as_bytes().to_vec())
|
||||||
|
|
|
@ -42,7 +42,7 @@ fn main() {
|
||||||
Ok(http_response) => responder.respond(http_response),
|
Ok(http_response) => responder.respond(http_response),
|
||||||
Err(e) => responder.respond(
|
Err(e) => responder.respond(
|
||||||
ResponseBuilder::new()
|
ResponseBuilder::new()
|
||||||
.status(StatusCode::BAD_REQUEST)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(CONTENT_TYPE, "text/plain")
|
.header(CONTENT_TYPE, "text/plain")
|
||||||
.body(e.to_string().as_bytes().to_vec())
|
.body(e.to_string().as_bytes().to_vec())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|
Loading…
Reference in New Issue