1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-28 04:44:06 +00:00

Improve Error Handling (#459)

* Add error messages by changing unwrap() calls to expect()

* Improve error messages by changing println! to info!/warn!/error!

* Address nits

* Change panic message

* details in panic
This commit is contained in:
asimon-1 2023-01-27 11:19:18 -08:00 committed by GitHub
parent b28522a6ce
commit 77f439a6eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 150 additions and 105 deletions

View file

@ -31,6 +31,7 @@ toml = "0.5.9"
training_mod_consts = { path = "training_mod_consts" } training_mod_consts = { path = "training_mod_consts" }
training_mod_tui = { path = "training_mod_tui" } training_mod_tui = { path = "training_mod_tui" }
native-tls = { version = "0.2.11", features = ["vendored"] } native-tls = { version = "0.2.11", features = ["vendored"] }
log = "0.4.17"
[patch.crates-io] [patch.crates-io]
native-tls = { git = "https://github.com/skyline-rs/rust-native-tls", rev = "f202fca" } native-tls = { git = "https://github.com/skyline-rs/rust-native-tls", rev = "f202fca" }

View file

@ -61,7 +61,7 @@ struct TopLevelBtnComboConfig {
} }
pub fn validate_config(data: &str) -> bool { pub fn validate_config(data: &str) -> bool {
let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap(); let conf: TopLevelBtnComboConfig = toml::from_str(data).expect("Custom button config has invalid schema");
let conf = conf.button_config; let conf = conf.button_config;
let configs = [conf.open_menu, conf.save_state, conf.load_state]; let configs = [conf.open_menu, conf.save_state, conf.load_state];
let bad_keys = configs let bad_keys = configs
@ -117,7 +117,7 @@ pub fn save_all_btn_config_from_defaults() {
} }
pub fn save_all_btn_config_from_toml(data: &str) { pub fn save_all_btn_config_from_toml(data: &str) {
let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap(); let conf: TopLevelBtnComboConfig = toml::from_str(data).expect("Could not parse button config");
unsafe { unsafe {
// This println is necessary. Why?....... // This println is necessary. Why?.......
println!("{:?}", &conf.button_config.load_state.press); println!("{:?}", &conf.button_config.load_state.press);

View file

@ -1,6 +1,7 @@
use crate::common::*; use crate::common::*;
use crate::events::{Event, EVENT_QUEUE}; use crate::events::{Event, EVENT_QUEUE};
use crate::training::frame_counter; use crate::training::frame_counter;
use crate::logging::*;
use ramhorns::Template; use ramhorns::Template;
use skyline::info::get_program_id; use skyline::info::get_program_id;
@ -57,11 +58,7 @@ pub unsafe fn write_menu() {
.join(format!("{program_id:016X}")) .join(format!("{program_id:016X}"))
.join(format!("manual_html/html-document/{htdocs_dir}.htdocs/")) .join(format!("manual_html/html-document/{htdocs_dir}.htdocs/"))
.join("training_menu.html"); .join("training_menu.html");
fs::write(menu_html_path, data).expect("Failed to write menu HTML file");
let write_resp = fs::write(menu_html_path, data);
if write_resp.is_err() {
println!("Error!: {}", write_resp.err().unwrap());
}
} }
const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json"; const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json";
@ -69,7 +66,7 @@ const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json";
pub unsafe fn set_menu_from_json(message: &str) { pub unsafe fn set_menu_from_json(message: &str) {
let web_response = serde_json::from_str::<MenuJsonStruct>(message); let web_response = serde_json::from_str::<MenuJsonStruct>(message);
let tui_response = serde_json::from_str::<TrainingModpackMenu>(message); let tui_response = serde_json::from_str::<TrainingModpackMenu>(message);
println!("Received menu message: {message}"); info!("Received menu message: {message}");
if let Ok(message_json) = web_response { if let Ok(message_json) = web_response {
// Includes both MENU and DEFAULTS_MENU // Includes both MENU and DEFAULTS_MENU
// From Web Applet // From Web Applet
@ -79,7 +76,7 @@ pub unsafe fn set_menu_from_json(message: &str) {
MENU_CONF_PATH, MENU_CONF_PATH,
serde_json::to_string_pretty(&message_json).unwrap(), serde_json::to_string_pretty(&message_json).unwrap(),
) )
.expect("Failed to write menu settings file"); .expect("Failed to write menu settings file from web response");
} else if let Ok(message_json) = tui_response { } else if let Ok(message_json) = tui_response {
// Only includes MENU // Only includes MENU
// From TUI // From TUI
@ -90,7 +87,7 @@ pub unsafe fn set_menu_from_json(message: &str) {
defaults_menu: DEFAULTS_MENU, defaults_menu: DEFAULTS_MENU,
}; };
std::fs::write(MENU_CONF_PATH, serde_json::to_string_pretty(&conf).unwrap()) std::fs::write(MENU_CONF_PATH, serde_json::to_string_pretty(&conf).unwrap())
.expect("Failed to write menu settings file"); .expect("Failed to write menu settings file from quick menu response");
} else { } else {
skyline::error::show_error( skyline::error::show_error(
0x70, 0x70,
@ -348,10 +345,10 @@ pub unsafe fn quick_menu_loop() {
static mut WEB_MENU_ACTIVE: bool = false; static mut WEB_MENU_ACTIVE: bool = false;
unsafe fn spawn_web_session(session: WebSession) { unsafe fn spawn_web_session(session: WebSession) {
println!("[Training Modpack] Opening menu session..."); info!("Opening menu session...");
let loaded_msg = session.recv(); let loaded_msg = session.recv();
println!( info!(
"[Training Modpack] Received loaded message from web: {}", "Received loaded message from web: {}",
&loaded_msg &loaded_msg
); );
let message_send = MenuJsonStruct { let message_send = MenuJsonStruct {
@ -360,7 +357,7 @@ unsafe fn spawn_web_session(session: WebSession) {
}; };
session.send_json(&message_send); session.send_json(&message_send);
let message_recv = session.recv(); let message_recv = session.recv();
println!("[Training Modpack] Tearing down Training Modpack menu session"); info!("Tearing down Training Modpack menu session");
session.exit(); session.exit();
session.wait_for_exit(); session.wait_for_exit();
set_menu_from_json(&message_recv); set_menu_from_json(&message_recv);
@ -399,7 +396,7 @@ pub unsafe fn web_session_loop() {
// Starting a new session causes some ingame lag. // Starting a new session causes some ingame lag.
// Investigate whether we can minimize this lag by // Investigate whether we can minimize this lag by
// waiting until the player is idle or using CPU boost mode // waiting until the player is idle or using CPU boost mode
println!("[Training Modpack] Starting new menu session..."); info!("Starting new menu session...");
web_session = Some(new_web_session(true)); web_session = Some(new_web_session(true));
} }
} else { } else {
@ -407,7 +404,7 @@ pub unsafe fn web_session_loop() {
// This will avoid conflicts with other web plugins, and helps with stability. // This will avoid conflicts with other web plugins, and helps with stability.
// Having the session open too long, especially if the switch has been put to sleep, can cause freezes // Having the session open too long, especially if the switch has been put to sleep, can cause freezes
if let Some(web_session_to_kill) = web_session { if let Some(web_session_to_kill) = web_session {
println!("[Training Modpack] Tearing down Training Modpack menu session"); info!("Tearing down Training Modpack menu session");
web_session_to_kill.exit(); web_session_to_kill.exit();
web_session_to_kill.wait_for_exit(); web_session_to_kill.wait_for_exit();
} }

View file

@ -1,5 +1,6 @@
use skyline_web::DialogOk; use skyline_web::DialogOk;
use std::fs; use std::fs;
use crate::logging::*;
pub const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION"); pub const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt"; const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt";
@ -44,9 +45,9 @@ pub fn version_check() {
) )
); );
// Remove old menu selections, silently ignoring errors (i.e. if the file doesn't exist) // Remove old menu selections, silently ignoring errors (i.e. if the file doesn't exist)
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.conf").unwrap(); fs::remove_file("sd:/TrainingModpack/training_modpack_menu.conf").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu.conf"));
fs::remove_file("sd:/TrainingModpack/training_modpack_menu.json").unwrap(); fs::remove_file("sd:/TrainingModpack/training_modpack_menu.json").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu.json"));
fs::remove_file("sd:/TrainingModpack/training_modpack_menu_defaults.conf").unwrap(); fs::remove_file("sd:/TrainingModpack/training_modpack_menu_defaults.conf").unwrap_or_else(|_| error!("Couldn't remove training_modpack_menu_defaults.conf"));
record_current_version(VERSION_FILE_PATH); record_current_version(VERSION_FILE_PATH);
} }
VersionCheck::NoFile => { VersionCheck::NoFile => {

View file

@ -2,6 +2,7 @@
#![allow(unused_assignments)] #![allow(unused_assignments)]
#![allow(unused_variables)] #![allow(unused_variables)]
use crate::common::consts::*; use crate::common::consts::*;
use crate::logging::*;
use skyline::error::show_error; use skyline::error::show_error;
use skyline::hook; use skyline::hook;
use skyline::hooks::A64InlineHook; use skyline::hooks::A64InlineHook;
@ -127,7 +128,7 @@ unsafe fn validate_hazards_addrs() -> std::result::Result<(), ()> {
} }
pub fn hazard_manager() { pub fn hazard_manager() {
println!("[Training Modpack] Applying hazard control mods."); info!("Applying hazard control mods.");
unsafe { unsafe {
if let Ok(()) = validate_hazards_addrs() { if let Ok(()) = validate_hazards_addrs() {
HAZARD_FLAG_ADDRESS = get_hazard_flag_address() as *mut u8; HAZARD_FLAG_ADDRESS = get_hazard_flag_address() as *mut u8;

View file

@ -1,4 +1,5 @@
use crate::common::{consts::*, *}; use crate::common::{consts::*, *};
use crate::logging::*;
use smash::app::{self, lua_bind::*, sv_animcmd, sv_system}; use smash::app::{self, lua_bind::*, sv_animcmd, sv_system};
use smash::lib::{lua_const::*, L2CAgent, L2CValue}; use smash::lib::{lua_const::*, L2CAgent, L2CValue};
use smash::phx::{Hash40, Vector3f}; use smash::phx::{Hash40, Vector3f};
@ -369,6 +370,6 @@ unsafe fn mod_handle_handle_set_rebound(
} }
pub fn hitbox_visualization() { pub fn hitbox_visualization() {
println!("[Training Modpack] Applying hitbox visualization mods."); info!("Applying hitbox visualization mods.");
skyline::install_hooks!(handle_attack, handle_catch, handle_set_rebound); skyline::install_hooks!(handle_attack, handle_catch, handle_set_rebound);
} }

View file

@ -23,6 +23,7 @@ mod training;
#[cfg(test)] #[cfg(test)]
mod test; mod test;
mod logging;
use crate::common::*; use crate::common::*;
use crate::events::{Event, EVENT_QUEUE}; use crate::events::{Event, EVENT_QUEUE};
@ -34,8 +35,8 @@ use std::fs;
use crate::menu::quick_menu_loop; use crate::menu::quick_menu_loop;
#[cfg(feature = "web_session_preload")] #[cfg(feature = "web_session_preload")]
use crate::menu::web_session_loop; use crate::menu::web_session_loop;
use owo_colors::OwoColorize;
use training_mod_consts::{MenuJsonStruct, OnOff}; use training_mod_consts::{MenuJsonStruct, OnOff};
use crate::logging::*;
fn nro_main(nro: &NroInfo<'_>) { fn nro_main(nro: &NroInfo<'_>) {
if nro.module.isLoaded { if nro.module.isLoaded {
@ -70,21 +71,16 @@ pub fn main() {
}, },
}; };
let err_msg = format!("thread has panicked at '{msg}', {location}"); let err_msg = format!("SSBU Training Modpack has panicked at '{msg}', {location}");
skyline::error::show_error( skyline::error::show_error(
69, 69,
"Skyline plugin has panicked! Please open the details and send a screenshot to the developer, then close the game.\n", "SSBU Training Modpack has panicked! Please open the details and send a screenshot to the developer, then close the game.\n",
err_msg.as_str(), err_msg.as_str(),
); );
})); }));
init_logger().unwrap();
macro_rules! log { info!("Initialized.");
($($arg:tt)*) => {
println!("{}{}", "[Training Modpack] ".green(), format!($($arg)*));
};
}
log!("Initialized.");
unsafe { unsafe {
EVENT_QUEUE.push(Event::smash_open()); EVENT_QUEUE.push(Event::smash_open());
} }
@ -102,46 +98,43 @@ pub fn main() {
let ovl_path = "sd:/switch/.overlays/ovlTrainingModpack.ovl"; let ovl_path = "sd:/switch/.overlays/ovlTrainingModpack.ovl";
if fs::metadata(ovl_path).is_ok() { if fs::metadata(ovl_path).is_ok() {
log!("Removing ovlTrainingModpack.ovl..."); warn!("Removing ovlTrainingModpack.ovl...");
fs::remove_file(ovl_path).unwrap(); fs::remove_file(ovl_path).expect(&format!("Could not remove {}", ovl_path));
} }
log!("Performing version check..."); info!("Performing version check...");
release::version_check(); release::version_check();
let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.json"; let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.json";
log!("Checking for previous menu in training_modpack_menu.json..."); info!("Checking for previous menu in training_modpack_menu.json...");
if fs::metadata(menu_conf_path).is_ok() { if fs::metadata(menu_conf_path).is_ok() {
let menu_conf = fs::read_to_string(menu_conf_path).unwrap(); let menu_conf = fs::read_to_string(menu_conf_path).expect(&format!("Could not remove {}", menu_conf_path));
if let Ok(menu_conf_json) = serde_json::from_str::<MenuJsonStruct>(&menu_conf) { if let Ok(menu_conf_json) = serde_json::from_str::<MenuJsonStruct>(&menu_conf) {
unsafe { unsafe {
MENU = menu_conf_json.menu; MENU = menu_conf_json.menu;
DEFAULTS_MENU = menu_conf_json.defaults_menu; DEFAULTS_MENU = menu_conf_json.defaults_menu;
log!("Previous menu found. Loading..."); info!("Previous menu found. Loading...");
}
} else if menu_conf.starts_with("http://localhost") {
log!("Previous menu found, with URL schema. Deleting...");
fs::remove_file(menu_conf_path).expect("Could not delete menu conf file!");
} else {
log!("Previous menu found but is invalid. Deleting...");
fs::remove_file(menu_conf_path).expect("Could not delete menu conf file!");
} }
} else { } else {
log!("No previous menu file found."); warn!("Previous menu found but is invalid. Deleting...");
fs::remove_file(menu_conf_path).expect(&format!("{} has invalid schema but could not be deleted!", menu_conf_path));
}
} else {
info!("No previous menu file found.");
} }
let combo_path = "sd:/TrainingModpack/training_modpack.toml"; let combo_path = "sd:/TrainingModpack/training_modpack.toml";
log!("Checking for previous button combo settings in training_modpack.toml..."); info!("Checking for previous button combo settings in training_modpack.toml...");
if fs::metadata(combo_path).is_ok() { if fs::metadata(combo_path).is_ok() {
log!("Previous button combo settings found. Loading..."); info!("Previous button combo settings found. Loading...");
let combo_conf = fs::read_to_string(combo_path).unwrap(); let combo_conf = fs::read_to_string(combo_path).expect(&format!("Could not read {}", combo_path));
if button_config::validate_config(&combo_conf) { if button_config::validate_config(&combo_conf) {
button_config::save_all_btn_config_from_toml(&combo_conf); button_config::save_all_btn_config_from_toml(&combo_conf);
} else { } else {
button_config::save_all_btn_config_from_defaults(); button_config::save_all_btn_config_from_defaults();
} }
} else { } else {
log!("No previous button combo file found. Creating..."); info!("No previous button combo file found. Creating...");
fs::write(combo_path, button_config::DEFAULT_BTN_CONFIG) fs::write(combo_path, button_config::DEFAULT_BTN_CONFIG)
.expect("Failed to write button config conf file"); .expect("Failed to write button config conf file");
button_config::save_all_btn_config_from_defaults(); button_config::save_all_btn_config_from_defaults();
@ -166,7 +159,7 @@ pub fn main() {
); );
let url = format!("{host}{path}"); let url = format!("{host}{path}");
minreq::post(url).with_json(&event).unwrap().send().ok(); minreq::post(url).with_json(&event).expect("Failed to send info to firebase").send().ok();
} }
} }
}); });

50
src/logging.rs Normal file
View file

@ -0,0 +1,50 @@
pub use log::{error, info, warn};
use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
use owo_colors::OwoColorize;
struct TrainingModpackLogger;
impl log::Log for TrainingModpackLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Info
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
match record.level() {
Level::Error => {
println!(
"[TrainingModpack] [{}] {}",
record.level().red(),
record.args()
);
}
Level::Warn => {
println!(
"[TrainingModpack] [{}] {}",
record.level().yellow(),
record.args()
);
}
Level::Info => {
println!(
"[TrainingModpack] [{}] {}",
record.level().cyan(),
record.args()
);
}
_ => {
println!("[TrainingModpack] [{}] {}", record.level(), record.args());
}
};
}
}
fn flush(&self) {}
}
static LOGGER: TrainingModpackLogger = TrainingModpackLogger;
pub fn init_logger() -> Result<(), SetLoggerError> {
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info))
}

View file

@ -3,6 +3,7 @@ use crate::common::{
}; };
use crate::hitbox_visualizer; use crate::hitbox_visualizer;
use crate::training::character_specific::items; use crate::training::character_specific::items;
use crate::logging::*;
use skyline::hooks::{getRegionAddress, InlineCtx, Region}; use skyline::hooks::{getRegionAddress, InlineCtx, Region};
use skyline::nn::hid::*; use skyline::nn::hid::*;
use skyline::nn::ro::LookupSymbol; use skyline::nn::ro::LookupSymbol;
@ -476,7 +477,7 @@ extern "C" {
} }
pub fn training_mods() { pub fn training_mods() {
println!("[Training Modpack] Applying training mods."); info!("Applying training mods.");
// Input Recording/Delay // Input Recording/Delay
unsafe { unsafe {