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
This commit is contained in:
Tensor-Programming 2020-01-30 07:33:42 -05:00 committed by GitHub
parent 793b002344
commit fc0715f8e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 42 deletions

View File

@ -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 = []

View File

@ -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;

View File

@ -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(

View File

@ -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())
}
},

View File

@ -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())
})
},

View File

@ -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,