feat: starting to get pretty error messages
This commit is contained in:
@@ -1,18 +1,80 @@
|
||||
use std::{io, path::PathBuf};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
io,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use aiken_lang::error::ParseError;
|
||||
use miette::{EyreContext, LabeledSpan, MietteHandlerOpts, RgbColors, SourceCode};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
|
||||
#[derive(thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("file operation failed")]
|
||||
FileIo { path: PathBuf, error: io::Error },
|
||||
#[error("failed to parse Aiken source code")]
|
||||
#[error("failed to parse")]
|
||||
Parse {
|
||||
path: PathBuf,
|
||||
|
||||
src: String,
|
||||
|
||||
#[source]
|
||||
error: Box<ParseError>,
|
||||
},
|
||||
#[error("list of errors")]
|
||||
/// Useful for returning many [`Error::Parse`] at once
|
||||
#[error("a list of errors")]
|
||||
List(Vec<Self>),
|
||||
}
|
||||
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let miette_handler = MietteHandlerOpts::new()
|
||||
// For better support of terminal themes use the ANSI coloring
|
||||
.rgb_colors(RgbColors::Never)
|
||||
// If ansi support is disabled in the config disable the eye-candy
|
||||
.color(true)
|
||||
.unicode(true)
|
||||
.terminal_links(true)
|
||||
.build();
|
||||
|
||||
// Ignore error to prevent format! panics. This can happen if span points at some
|
||||
// inaccessible location, for example by calling `report_error()` with wrong working set.
|
||||
let _ = miette_handler.debug(self, f);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl miette::Diagnostic for Error {
|
||||
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||
match self {
|
||||
Error::Parse { .. } => Some(Box::new("aiken::parser".to_string())),
|
||||
Error::FileIo { .. } => None,
|
||||
Error::List(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn source_code(&self) -> Option<&dyn SourceCode> {
|
||||
match self {
|
||||
Error::Parse { src, .. } => Some(src),
|
||||
Error::FileIo { .. } => None,
|
||||
Error::List(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
|
||||
match self {
|
||||
Error::Parse { error, .. } => error.labels(),
|
||||
Error::FileIo { .. } => None,
|
||||
Error::List(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||
match self {
|
||||
Error::Parse { error, .. } => error.kind.help(),
|
||||
Error::FileIo { .. } => None,
|
||||
Error::List(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,15 @@ use uplc::{
|
||||
},
|
||||
};
|
||||
|
||||
use aiken::{config::Config, project::Project};
|
||||
use aiken::{config::Config, error, project::Project};
|
||||
|
||||
mod args;
|
||||
|
||||
use args::{Args, TxCommand, UplcCommand};
|
||||
|
||||
fn main() -> miette::Result<()> {
|
||||
miette::set_panic_hook();
|
||||
|
||||
let args = Args::default();
|
||||
|
||||
match args {
|
||||
@@ -47,7 +49,16 @@ fn main() -> miette::Result<()> {
|
||||
|
||||
let mut project = Project::new(config, project_path);
|
||||
|
||||
project.build()?;
|
||||
if let Err(err) = project.build() {
|
||||
match err {
|
||||
error::Error::List(errors) => {
|
||||
for error in errors {
|
||||
eprintln!("Error: {:?}", error)
|
||||
}
|
||||
}
|
||||
rest => Err(rest)?,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Args::Dev => {
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct Source {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
struct ParsedModule {
|
||||
path: PathBuf,
|
||||
name: String,
|
||||
|
||||
Reference in New Issue
Block a user