diff --git a/tauri/Cargo.toml b/tauri/Cargo.toml index 1f74897c4..89a3293dc 100644 --- a/tauri/Cargo.toml +++ b/tauri/Cargo.toml @@ -23,6 +23,7 @@ lazy_static = "1.4.0" tiny_http = "0.6" threadpool = "1.7" uuid = { version = "0.8.1", features = ["v4"] } +error-chain = "0.12.1" tauri-api = { version = "0.3", path = "../tauri-api" } @@ -47,3 +48,4 @@ setTitle = [] execute = [] open = [] event = [] +updater = [] \ No newline at end of file diff --git a/tauri/src/app/runner.rs b/tauri/src/app/runner.rs index 01d42a01d..61d3fcfb5 100644 --- a/tauri/src/app/runner.rs +++ b/tauri/src/app/runner.rs @@ -7,7 +7,6 @@ use super::App; use crate::config::{get, Config}; #[cfg(feature = "embedded-server")] use crate::tcp::{get_available_port, port_is_available}; -use crate::TauriResult; // JavaScript string literal const JS_STRING: &'static str = r#" @@ -31,7 +30,7 @@ Object.defineProperty(window, 'onTauriInit', { "#; // Main entry point function for running the Webview -pub(crate) fn run(application: &mut App) -> TauriResult<()> { +pub(crate) fn run(application: &mut App) -> crate::Result<()> { // get the tauri config struct let config = get()?; @@ -74,7 +73,7 @@ pub(crate) fn run(application: &mut App) -> TauriResult<()> { // setup content for dev-server #[cfg(not(any(feature = "embedded-server", feature = "no-server")))] -fn setup_content(config: Config) -> TauriResult> { +fn setup_content(config: Config) -> crate::Result> { if config.build.dev_path.starts_with("http") { Ok(Content::Url(config.build.dev_path)) } else { @@ -85,7 +84,7 @@ fn setup_content(config: Config) -> TauriResult> { // setup content for embedded server #[cfg(feature = "embedded-server")] -fn setup_content(config: Config) -> TauriResult> { +fn setup_content(config: Config) -> crate::Result> { let (port, valid) = setup_port(config.clone()).expect("Unable to setup Port"); let url = setup_server_url(config.clone(), valid, port).expect("Unable to setup URL"); @@ -94,7 +93,7 @@ fn setup_content(config: Config) -> TauriResult> { // setup content for no-server #[cfg(feature = "no-server")] -fn setup_content(_: Config) -> TauriResult> { +fn setup_content(_: Config) -> crate::Result> { let index_path = Path::new(env!("TAURI_DIST_DIR")).join("index.tauri.html"); Ok(Content::Html(read_to_string(index_path)?)) } @@ -134,7 +133,7 @@ fn setup_server_url(config: Config, valid: bool, port: String) -> Option // spawn the embedded server #[cfg(feature = "embedded-server")] -fn spawn_server(server_url: String) -> TauriResult<()> { +fn spawn_server(server_url: String) -> crate::Result<()> { spawn(move || { let server = tiny_http::Server::http( server_url @@ -160,13 +159,10 @@ fn spawn_server(server_url: String) -> TauriResult<()> { // spawn an updater process. #[cfg(feature = "updater")] -fn spawn_updater() -> TauriResult<()> { +fn spawn_updater() -> crate::Result<()> { spawn(|| { - tauri_api::command::spawn_relative_command( - "updater".to_string(), - Vec::new(), - Stdio::inherit(), - )?; + tauri_api::command::spawn_relative_command("updater".to_string(), Vec::new(), Stdio::inherit()) + .expect("Unable to spawn relative command"); }); Ok(()) } @@ -176,7 +172,7 @@ fn build_webview( application: &mut App, config: Config, content: Content, -) -> TauriResult> { +) -> crate::Result> { let debug = cfg!(debug_assertions); // get properties from config struct let width = config.tauri.window.width; diff --git a/tauri/src/config.rs b/tauri/src/config.rs index e2d4e09b2..fa8cd1159 100644 --- a/tauri/src/config.rs +++ b/tauri/src/config.rs @@ -1,7 +1,5 @@ use std::env; -use crate::TauriResult; - #[derive(Deserialize, Clone)] #[serde(tag = "window", rename_all = "camelCase")] pub struct WindowConfig { @@ -106,7 +104,7 @@ fn default_build() -> BuildConfig { } } -pub fn get() -> TauriResult { +pub fn get() -> crate::Result { match option_env!("TAURI_CONFIG") { Some(config) => Ok(serde_json::from_str(config).expect("failed to parse TAURI_CONFIG env")), None => Ok( diff --git a/tauri/src/endpoints.rs b/tauri/src/endpoints.rs index 86b1b046b..43c76e2dd 100644 --- a/tauri/src/endpoints.rs +++ b/tauri/src/endpoints.rs @@ -2,10 +2,8 @@ mod cmd; use web_view::WebView; -use crate::TauriResult; - #[allow(unused_variables)] -pub(crate) fn handle(webview: &mut WebView<'_, T>, arg: &str) -> TauriResult { +pub(crate) fn handle(webview: &mut WebView<'_, T>, arg: &str) -> crate::Result { use cmd::Cmd::*; match serde_json::from_str(arg) { Err(_) => Ok(false), @@ -113,7 +111,7 @@ pub(crate) fn handle(webview: &mut WebView<'_, T>, arg: &str) -> Tau } } -fn init() -> TauriResult { +fn init() -> crate::Result { #[cfg(not(any(feature = "all-api", feature = "event")))] return Ok(String::from("")); #[cfg(any(feature = "all-api", feature = "event"))] @@ -151,7 +149,7 @@ fn init() -> TauriResult { } #[cfg(any(feature = "all-api", feature = "open"))] -fn open_fn(uri: String) -> TauriResult<()> { +fn open_fn(uri: String) -> crate::Result<()> { crate::spawn(move || { #[cfg(test)] assert!(uri.contains("http://")); @@ -164,7 +162,7 @@ fn open_fn(uri: String) -> TauriResult<()> { } #[cfg(any(feature = "all-api", feature = "event"))] -fn listen_fn(event: String, handler: String, once: bool) -> TauriResult { +fn listen_fn(event: String, handler: String, once: bool) -> crate::Result { Ok(format!( "if (window['{listeners}'] === void 0) {{ window['{listeners}'] = {{}} @@ -198,7 +196,7 @@ fn load_asset( asset_type: String, callback: String, error: String, -) -> TauriResult<()> { +) -> crate::Result<()> { let handle = webview.handle(); crate::execute_promise( webview, @@ -210,7 +208,7 @@ fn load_asset( asset )); if read_asset.is_err() { - return Err(format!("Asset '{}' not found", asset)); + return Err(format!("Asset '{}' not found", asset).into()); } if asset_type == "image" { @@ -230,15 +228,15 @@ fn load_asset( handle .dispatch(move |_webview| { let asset_bytes = &read_asset.expect("Failed to read asset type").into_owned(); - let asset_str = &std::str::from_utf8(asset_bytes) - .expect("failed to convert asset bytes to u8 slice"); + let asset_str = + &std::str::from_utf8(asset_bytes).expect("failed to convert asset bytes to u8 slice"); if asset_type == "stylesheet" { _webview.inject_css(asset_str) } else { _webview.eval(asset_str) } }) - .map_err(|err| format!("`{}`", err)) + .map_err(|err| crate::ErrorKind::Promise(format!("`{}`", err)).into()) .map(|_| r#""Asset loaded successfully""#.to_string()) } }, diff --git a/tauri/src/file_system.rs b/tauri/src/file_system.rs index aeb510a8b..c71f32181 100644 --- a/tauri/src/file_system.rs +++ b/tauri/src/file_system.rs @@ -16,8 +16,8 @@ pub fn list( webview, move || { dir::walk_dir(path.to_string()) - .map_err(|e| e.to_string()) - .and_then(|f| serde_json::to_string(&f).map_err(|err| err.to_string())) + .map_err(|e| crate::ErrorKind::Command(e.to_string()).into()) + .and_then(|f| serde_json::to_string(&f).map_err(|err| err.into())) }, callback, error, @@ -34,8 +34,8 @@ pub fn list_dirs( webview, move || { dir::list_dir_contents(&path) - .map_err(|e| e.to_string()) - .and_then(|f| serde_json::to_string(&f).map_err(|err| err.to_string())) + .map_err(|e| crate::ErrorKind::Command(e.to_string()).into()) + .and_then(|f| serde_json::to_string(&f).map_err(|err| err.into())) }, callback, error, @@ -53,10 +53,10 @@ pub fn write_file( webview, move || { File::create(file) - .map_err(|err| err.to_string()) + .map_err(|e| crate::ErrorKind::Command(e.to_string()).into()) .and_then(|mut f| { f.write_all(contents.as_bytes()) - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) .map(|_| "".to_string()) }) }, @@ -75,10 +75,10 @@ pub fn read_text_file( webview, move || { file::read_string(path) - .map_err(|e| e.to_string()) + .map_err(|e| crate::ErrorKind::Command(e.to_string()).into()) .and_then(|f| { serde_json::to_string(&f) - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) .map(|s| s.to_string()) }) }, @@ -97,10 +97,10 @@ pub fn read_binary_file( webview, move || { file::read_binary(path) - .map_err(|e| e.to_string()) + .map_err(|e| crate::ErrorKind::Command(e.to_string()).into()) .and_then(|f| { serde_json::to_string(&f) - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) .map(|s| s.to_string()) }) }, diff --git a/tauri/src/lib.rs b/tauri/src/lib.rs index 2aa7a5829..4c2dae740 100644 --- a/tauri/src/lib.rs +++ b/tauri/src/lib.rs @@ -33,13 +33,31 @@ use std::process::Stdio; use threadpool::ThreadPool; +use error_chain::error_chain; + pub use app::*; use web_view::WebView; pub use tauri_api as api; -// Result alias -type TauriResult = Result>; +error_chain! { + foreign_links{ + Api(::tauri_api::Error); + Json(::serde_json::Error); + Webview(::web_view::Error); + Io(::std::io::Error); + } + errors{ + Promise(t: String) { + description("Promise Error") + display("Promise Error: '{}'", t) + } + Command(t: String) { + description("Command Error") + display("Command Error: '{}'", t) + } + } +} thread_local!(static POOL: ThreadPool = ThreadPool::new(4)); @@ -51,7 +69,7 @@ pub fn spawn () + Send + 'static>(task: F) { }); } -pub fn execute_promise Result + Send + 'static>( +pub fn execute_promise crate::Result + Send + 'static>( webview: &mut WebView<'_, T>, task: F, callback: String, @@ -60,7 +78,8 @@ pub fn execute_promise Result + Send let handle = webview.handle(); POOL.with(|thread| { thread.execute(move || { - let callback_string = api::rpc::format_callback_result(task(), callback, error); + let callback_string = + api::rpc::format_callback_result(task().map_err(|err| err.to_string()), callback, error); handle .dispatch(move |_webview| _webview.eval(callback_string.as_str())) .expect("Failed to dispatch promise callback") @@ -79,7 +98,7 @@ pub fn call( webview, || { api::command::get_output(command, args, Stdio::piped()) - .map_err(|err| format!("`{}`", err)) + .map_err(|err| crate::ErrorKind::Promise(err.to_string()).into()) .map(|output| format!("`{}`", output)) }, callback,