1
0

Clean up errors; Add more pretty errors

This commit is contained in:
Jeff 2024-02-16 18:54:00 -05:00
parent bda217135e
commit fd33f330f7
7 changed files with 147 additions and 67 deletions

View File

@ -90,11 +90,24 @@ impl AbstractTree for As {
} }
_ => { _ => {
return Err(RuntimeError::ConversionImpossible { return Err(RuntimeError::ConversionImpossible {
value, from: value.r#type()?,
target_type: self.r#type.clone(), to: self.r#type.clone(),
position: self.position.clone(),
}); });
} }
} }
} else if let Type::Integer = self.r#type {
match value {
Value::Integer(integer) => Value::Integer(integer),
Value::Float(float) => Value::Integer(float as i64),
_ => {
return Err(RuntimeError::ConversionImpossible {
from: value.r#type()?,
to: self.r#type.clone(),
position: self.position.clone(),
})
}
}
} else { } else {
todo!() todo!()
}; };

View File

@ -102,21 +102,18 @@ impl Callable for BuiltInFunction {
let left = arguments.get(0).unwrap(); let left = arguments.get(0).unwrap();
let right = arguments.get(1).unwrap(); let right = arguments.get(1).unwrap();
let result = if left == right { if left == right {
Value::Enum(EnumInstance::new( Ok(Value::Enum(EnumInstance::new(
Identifier::new("Result"), Identifier::new("Result"),
Identifier::new("Ok"), Identifier::new("Ok"),
Some(Value::none()), Some(Value::none()),
)) )))
} else { } else {
Value::Enum(EnumInstance::new( Err(RuntimeError::AssertEqualFailed {
Identifier::new("Result"), left: left.clone(),
Identifier::new("Error"), right: right.clone(),
Some(Value::none()), })
)) }
};
Ok(result)
} }
BuiltInFunction::Fs(fs_function) => fs_function.call(arguments, _source, context), BuiltInFunction::Fs(fs_function) => fs_function.call(arguments, _source, context),
BuiltInFunction::Json(json_function) => json_function.call(arguments, _source, context), BuiltInFunction::Json(json_function) => json_function.call(arguments, _source, context),

View File

@ -7,8 +7,6 @@ pub(crate) mod rw_lock_error;
mod syntax_error; mod syntax_error;
mod validation_error; mod validation_error;
use colored::Colorize;
use lyneate::Report;
pub use runtime_error::RuntimeError; pub use runtime_error::RuntimeError;
pub use syntax_error::SyntaxError; pub use syntax_error::SyntaxError;
pub use validation_error::ValidationError; pub use validation_error::ValidationError;
@ -36,43 +34,13 @@ impl Error {
/// The `source` argument should be the full source code document that was /// The `source` argument should be the full source code document that was
/// used to create this error. /// used to create this error.
pub fn create_report(&self, source: &str) -> String { pub fn create_report(&self, source: &str) -> String {
let markers = if let Error::Syntax(SyntaxError::InvalidSource { position }) = self { match self {
vec![( Error::Syntax(syntax_error) => syntax_error.create_report(source),
position.start_byte..position.end_byte, Error::Validation(_) => todo!(),
format!( Error::Runtime(runtime_error) => runtime_error.create_report(source),
"Invalid syntax from ({}, {}) to ({}, {}).", Error::ParserCancelled => todo!(),
position.start_row, Error::Language(_) => todo!(),
position.start_column, }
position.end_row,
position.end_column,
),
(255, 200, 100),
)]
} else if let Error::Syntax(SyntaxError::UnexpectedSyntaxNode {
expected,
actual,
position,
}) = self
{
vec![(
position.start_byte..position.end_byte,
format!(
"Unexpected syntax from ({}, {}) to ({}, {}). {}",
position.start_row,
position.start_column,
position.end_row,
position.end_column,
format!("Expected {} but got {}.", expected, actual).dimmed(),
),
(255, 100, 100),
)]
} else {
vec![]
};
let report = Report::new_byte_spanned(source, markers);
report.display_str()
} }
} }

View File

@ -7,16 +7,31 @@ use std::{
time, time,
}; };
use crate::{Type, Value}; use colored::Colorize;
use lyneate::Report;
use crate::{SourcePosition, Type, Value};
use super::{rw_lock_error::RwLockError, ValidationError}; use super::{rw_lock_error::RwLockError, ValidationError};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum RuntimeError { pub enum RuntimeError {
/// The 'assert' macro did not resolve successfully.
AssertEqualFailed {
left: Value,
right: Value,
},
/// The 'assert' macro did not resolve successfully.
AssertFailed {
assertion: Value,
},
/// The attempted conversion is impossible. /// The attempted conversion is impossible.
ConversionImpossible { ConversionImpossible {
value: Value, from: Type,
target_type: Type, to: Type,
position: SourcePosition,
}, },
Csv(String), Csv(String),
@ -116,6 +131,68 @@ pub enum RuntimeError {
} }
impl RuntimeError { impl RuntimeError {
pub fn create_report(&self, source: &str) -> String {
let messages = match self {
RuntimeError::AssertEqualFailed {
left: expected,
right: actual,
} => {
vec![(
0..source.len(),
format!("\"assert_equal\" failed. {} != {}", expected, actual),
(200, 100, 100),
)]
}
RuntimeError::AssertFailed { assertion } => todo!(),
RuntimeError::ConversionImpossible { from, to, position } => vec![(
position.start_byte..position.end_byte,
format!(
"Impossible conversion. {}",
format!("Cannot convert from {from} to {to}.").dimmed()
),
(255, 100, 100),
)],
RuntimeError::Csv(_) => todo!(),
RuntimeError::Io(_) => todo!(),
RuntimeError::Reqwest(_) => todo!(),
RuntimeError::Json(_) => todo!(),
RuntimeError::SystemTime(_) => todo!(),
RuntimeError::Toml(_) => todo!(),
RuntimeError::ExpectedString { actual } => todo!(),
RuntimeError::ExpectedInteger { actual } => todo!(),
RuntimeError::ExpectedFloat { actual } => todo!(),
RuntimeError::ExpectedNumber { actual } => todo!(),
RuntimeError::ExpectedNumberOrString { actual } => todo!(),
RuntimeError::ExpectedBoolean { actual } => todo!(),
RuntimeError::ExpectedList { actual } => todo!(),
RuntimeError::ExpectedMinLengthList {
minimum_len,
actual_len,
} => todo!(),
RuntimeError::ExpectedFixedLenList {
expected_len,
actual,
} => todo!(),
RuntimeError::ExpectedNone { actual } => todo!(),
RuntimeError::ExpectedMap { actual } => todo!(),
RuntimeError::ExpectedTable { actual } => todo!(),
RuntimeError::ExpectedFunction { actual } => todo!(),
RuntimeError::ExpectedOption { actual } => todo!(),
RuntimeError::ExpectedCollection { actual } => todo!(),
RuntimeError::RwLock(_) => todo!(),
RuntimeError::ParseFloat(_) => todo!(),
RuntimeError::Utf8(_) => todo!(),
RuntimeError::ExpectedBuiltInFunctionArgumentAmount {
function_name,
expected,
actual,
} => todo!(),
RuntimeError::ValidationFailure(_) => todo!(),
};
Report::new_byte_spanned(source, messages).display_str()
}
pub fn expect_argument_amount( pub fn expect_argument_amount(
function_name: &str, function_name: &str,
expected: usize, expected: usize,

View File

@ -1,5 +1,6 @@
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use lyneate::Report;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node as SyntaxNode; use tree_sitter::Node as SyntaxNode;
@ -24,6 +25,32 @@ pub enum SyntaxError {
} }
impl SyntaxError { impl SyntaxError {
pub fn create_report(&self, source: &str) -> String {
let messages = match self {
SyntaxError::InvalidSource { position } => {
vec![(
position.start_byte..position.end_byte,
format!(
"Invalid syntax from ({}, {}) to ({}, {}).",
position.start_row,
position.start_column,
position.end_row,
position.end_column,
),
(255, 200, 100),
)]
}
SyntaxError::RwLock(_) => todo!(),
SyntaxError::UnexpectedSyntaxNode {
expected,
actual,
position,
} => todo!(),
};
Report::new_byte_spanned(source, messages).display_str()
}
pub fn expect_syntax_node(expected: &str, actual: SyntaxNode) -> Result<(), SyntaxError> { pub fn expect_syntax_node(expected: &str, actual: SyntaxNode) -> Result<(), SyntaxError> {
log::info!("Converting {} to abstract node", actual.kind()); log::info!("Converting {} to abstract node", actual.kind());

View File

@ -8,16 +8,6 @@ use super::rw_lock_error::RwLockError;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ValidationError { pub enum ValidationError {
/// The 'assert' macro did not resolve successfully.
AssertEqualFailed {
expected: Value,
actual: Value,
position: SourcePosition,
},
/// The 'assert' macro did not resolve successfully.
AssertFailed { position: SourcePosition },
/// Two value are incompatible for addition. /// Two value are incompatible for addition.
CannotAdd { left: Value, right: Value }, CannotAdd { left: Value, right: Value },

View File

@ -38,8 +38,16 @@ fn conversion_runtime_error() {
assert_eq!( assert_eq!(
interpret(&format!("json:parse('{JSON}') as [map]")), interpret(&format!("json:parse('{JSON}') as [map]")),
Err(Error::Runtime(RuntimeError::ConversionImpossible { Err(Error::Runtime(RuntimeError::ConversionImpossible {
value: json_value, from: json_value.r#type().unwrap(),
target_type: Type::List(Box::new(Type::Map)) to: Type::List(Box::new(Type::Map)),
position: SourcePosition {
start_byte: 0,
end_byte: 0,
start_row: 0,
start_column: 0,
end_row: 0,
end_column: 0
}
})) }))
) )
} }