Procházet zdrojové kódy

Refactor(Core) add error chain (#376)

* add updater feat and error_chain lib

* remove tauriresult and add error_chains

* cleanup endpoints and add Command error type
Tensor-Programming před 5 roky
rodič
revize
fc0715f8e7

+ 2 - 0
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 = []

+ 9 - 13
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<Content<String>> {
+fn setup_content(config: Config) -> crate::Result<Content<String>> {
   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<Content<String>> {
 
 // setup content for embedded server
 #[cfg(feature = "embedded-server")]
-fn setup_content(config: Config) -> TauriResult<Content<String>> {
+fn setup_content(config: Config) -> crate::Result<Content<String>> {
   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<Content<String>> {
 
 // setup content for no-server
 #[cfg(feature = "no-server")]
-fn setup_content(_: Config) -> TauriResult<Content<String>> {
+fn setup_content(_: Config) -> crate::Result<Content<String>> {
   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<String>
 
 // 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<String>,
-) -> TauriResult<WebView<'_, ()>> {
+) -> crate::Result<WebView<'_, ()>> {
   let debug = cfg!(debug_assertions);
   // get properties from config struct
   let width = config.tauri.window.width;

+ 1 - 3
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<Config> {
+pub fn get() -> crate::Result<Config> {
   match option_env!("TAURI_CONFIG") {
     Some(config) => Ok(serde_json::from_str(config).expect("failed to parse TAURI_CONFIG env")),
     None => Ok(

+ 9 - 11
tauri/src/endpoints.rs

@@ -2,10 +2,8 @@ mod cmd;
 
 use web_view::WebView;
 
-use crate::TauriResult;
-
 #[allow(unused_variables)]
-pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> TauriResult<bool> {
+pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> crate::Result<bool> {
   use cmd::Cmd::*;
   match serde_json::from_str(arg) {
     Err(_) => Ok(false),
@@ -113,7 +111,7 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> Tau
   }
 }
 
-fn init() -> TauriResult<String> {
+fn init() -> crate::Result<String> {
   #[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<String> {
 }
 
 #[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<String> {
+fn listen_fn(event: String, handler: String, once: bool) -> crate::Result<String> {
   Ok(format!(
     "if (window['{listeners}'] === void 0) {{
       window['{listeners}'] = {{}}
@@ -198,7 +196,7 @@ fn load_asset<T: 'static>(
   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<T: 'static>(
         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<T: 'static>(
         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())
       }
     },

+ 10 - 10
tauri/src/file_system.rs

@@ -16,8 +16,8 @@ pub fn list<T: 'static>(
     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<T: 'static>(
     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<T: 'static>(
     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<T: 'static>(
     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<T: 'static>(
     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())
         })
     },

+ 24 - 5
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<T> = Result<T, Box<dyn std::error::Error>>;
+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<F: FnOnce() -> () + Send + 'static>(task: F) {
   });
 }
 
-pub fn execute_promise<T: 'static, F: FnOnce() -> Result<String, String> + Send + 'static>(
+pub fn execute_promise<T: 'static, F: FnOnce() -> crate::Result<String> + Send + 'static>(
   webview: &mut WebView<'_, T>,
   task: F,
   callback: String,
@@ -60,7 +78,8 @@ pub fn execute_promise<T: 'static, F: FnOnce() -> Result<String, String> + 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<T: 'static>(
     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,