Improve error reporting

This commit is contained in:
Patrick Auernig 2023-08-16 14:33:55 +02:00
parent f17d128518
commit 18a0abcd62
4 changed files with 55 additions and 26 deletions

View File

@ -17,7 +17,7 @@ use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use ratatui::backend::CrosstermBackend;
use tracing::{debug, error, info};
use tracing::{debug, info};
use self::state::{Mode, State};
@ -104,6 +104,8 @@ fn run(terminal: &mut Terminal, mut state: State) -> Result<()> {
events::handle(&mut msg_tx, &mut state)?;
state.clear_expired_error_message();
match msg_rx.try_recv() {
Ok(Message::Exit) => {
debug!("Exiting...");
@ -111,8 +113,7 @@ fn run(terminal: &mut Terminal, mut state: State) -> Result<()> {
}
Ok(message) => {
if let Err(err) = handle_message(&mut state, &mut msg_tx, message) {
error!(message = ?err);
state.mode = Mode::ShowError(format!("{}", err));
state.show_error_message(err);
}
}
Err(TryRecvError::Empty) => (),
@ -174,18 +175,18 @@ fn handle_message(
Message::StartEditEntry => state.start_editing_entry(),
Message::CommitEditEntry => {
if let Err(err) = state.commit_entry_edit() {
error!(%err);
state.show_error_message(err);
}
}
Message::CancelEditEntry => state.cancel_editing_entry(),
Message::NextEntryValue => {
if let Err(err) = state.next_entry_value() {
error!(%err);
state.show_error_message(err);
}
}
Message::PreviousEntryValue => {
if let Err(err) = state.previous_entry_value() {
error!(%err);
state.show_error_message(err);
}
}
_ => (),

View File

@ -57,10 +57,6 @@ fn handle_keyboard_input(
msg_tx.send(Message::SetMode(Mode::Normal))?;
}
(Mode::ShowError(_), _) => {
msg_tx.send(Message::SetMode(Mode::Normal))?;
}
(Mode::SelectFile, KeyCode::Enter) => {
msg_tx.send(Message::LoadFile)?;
}
@ -147,5 +143,7 @@ fn handle_keyboard_input(
_ => (),
};
state.clear_error_message();
Ok(())
}

View File

@ -1,12 +1,14 @@
use core::fmt;
use std::fs::{self, create_dir_all, read_to_string};
use std::io::Write;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
use std::time::{Duration, Instant};
use anyhow::{bail, Context, Result};
use jrny_save::{RobeColor, Savefile, LEVEL_NAMES};
use ratatui::widgets::TableState;
use tracing::debug;
use tracing::{debug, error};
use tui_input::Input;
use super::view::info::glyphs::TABLE_RANGE as GLYPHS_TABLE_RANGE;
@ -27,8 +29,6 @@ pub enum Mode {
Insert,
ShowError(String),
SelectFile,
}
@ -57,6 +57,7 @@ pub struct State {
pub stats_table: TableState,
pub glyphs_table: TableState,
pub murals_table: TableState,
pub error_msg: Option<(Instant, String)>,
pub mode: Mode,
pub edit_input: Option<Input>,
pub file_select: Input,
@ -66,6 +67,29 @@ pub struct State {
impl State {
const ERROR_MSG_DURATION: Duration = Duration::new(3, 0);
pub fn show_error_message<S>(&mut self, msg: S)
where
S: fmt::Display,
{
let until = Instant::now() + Self::ERROR_MSG_DURATION;
error!(%msg);
self.error_msg = Some((until, msg.to_string()));
}
pub fn clear_expired_error_message(&mut self) {
if let Some((until, _)) = self.error_msg {
if Instant::now() >= until {
self.error_msg = None;
}
}
}
pub fn clear_error_message(&mut self) {
self.error_msg.take();
}
pub fn load() -> Result<Self> {
let data_dir = DIRS.data_local_dir();

View File

@ -6,21 +6,28 @@ use crate::tui::view::Frame;
use crate::tui::{Mode, State};
pub fn render(state: &State, mut frame: &mut Frame, area: Rect) {
pub fn render(state: &State, frame: &mut Frame, area: Rect) {
let status_block = Block::default().padding(Padding::horizontal(2));
match &state.mode {
Mode::ShowError(error_msg) => {
let error_msg = Paragraph::new(error_msg.clone())
match &state.error_msg {
Some((_, msg)) => render_error_message(&msg, frame, status_block, area),
None => render_status(state, frame, status_block, area),
}
}
fn render_error_message(msg: &str, frame: &mut Frame, block: Block, area: Rect) {
let error_msg = Paragraph::new(msg)
.style(Style::default().fg(ratatui::style::Color::LightRed))
.block(status_block);
.block(block);
frame.render_widget(error_msg, area);
}
pub fn render_status(state: &State, mut frame: &mut Frame, block: Block, area: Rect) {
match &state.mode {
Mode::Edit | Mode::Insert => {
if let Some(savefile) = &state.savefile {
let text = format!("Editing file: {}", savefile.path.display());
let status = Paragraph::new(text).block(status_block);
let status = Paragraph::new(text).block(block);
frame.render_widget(status, area);
}
}
@ -29,24 +36,23 @@ pub fn render(state: &State, mut frame: &mut Frame, area: Rect) {
Mode::Normal if state.is_watching_file() => {
if let Some(savefile) = &state.savefile {
let text = format!("Watching file: {}", savefile.path.display());
let status = Paragraph::new(text).block(status_block);
let status = Paragraph::new(text).block(block);
frame.render_widget(status, area);
}
}
Mode::SelectFile => render_file_select(&state, &mut frame, status_block, area),
Mode::SelectFile => render_file_select(&state, &mut frame, block, area),
_ => {
if let Some(savefile) = &state.savefile {
let text = format!("Showing file: {}", savefile.path.display());
let status = Paragraph::new(text).block(status_block);
let status = Paragraph::new(text).block(block);
frame.render_widget(status, area);
}
}
}
}
fn render_file_select(state: &State, frame: &mut Frame, block: Block, area: Rect) {
const PROMPT: &str = "Open file:";
const PADDING: usize = 2;