Improve error reporting
This commit is contained in:
parent
f17d128518
commit
18a0abcd62
@ -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);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user