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 {
value,
target_type: self.r#type.clone(),
from: value.r#type()?,
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 {
todo!()
};

View File

@ -102,21 +102,18 @@ impl Callable for BuiltInFunction {
let left = arguments.get(0).unwrap();
let right = arguments.get(1).unwrap();
let result = if left == right {
Value::Enum(EnumInstance::new(
if left == right {
Ok(Value::Enum(EnumInstance::new(
Identifier::new("Result"),
Identifier::new("Ok"),
Some(Value::none()),
))
)))
} else {
Value::Enum(EnumInstance::new(
Identifier::new("Result"),
Identifier::new("Error"),
Some(Value::none()),
))
};
Ok(result)
Err(RuntimeError::AssertEqualFailed {
left: left.clone(),
right: right.clone(),
})
}
}
BuiltInFunction::Fs(fs_function) => fs_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 validation_error;
use colored::Colorize;
use lyneate::Report;
pub use runtime_error::RuntimeError;
pub use syntax_error::SyntaxError;
pub use validation_error::ValidationError;
@ -36,43 +34,13 @@ impl Error {
/// The `source` argument should be the full source code document that was
/// used to create this error.
pub fn create_report(&self, source: &str) -> String {
let markers = if let Error::Syntax(SyntaxError::InvalidSource { position }) = self {
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),
)]
} 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()
match self {
Error::Syntax(syntax_error) => syntax_error.create_report(source),
Error::Validation(_) => todo!(),
Error::Runtime(runtime_error) => runtime_error.create_report(source),
Error::ParserCancelled => todo!(),
Error::Language(_) => todo!(),
}
}
}

View File

@ -7,16 +7,31 @@ use std::{
time,
};
use crate::{Type, Value};
use colored::Colorize;
use lyneate::Report;
use crate::{SourcePosition, Type, Value};
use super::{rw_lock_error::RwLockError, ValidationError};
#[derive(Debug, PartialEq)]
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.
ConversionImpossible {
value: Value,
target_type: Type,
from: Type,
to: Type,
position: SourcePosition,
},
Csv(String),
@ -116,6 +131,68 @@ pub enum 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(
function_name: &str,
expected: usize,

View File

@ -1,5 +1,6 @@
use std::fmt::{self, Display, Formatter};
use lyneate::Report;
use serde::{Deserialize, Serialize};
use tree_sitter::Node as SyntaxNode;
@ -24,6 +25,32 @@ pub enum 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> {
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)]
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.
CannotAdd { left: Value, right: Value },

View File

@ -38,8 +38,16 @@ fn conversion_runtime_error() {
assert_eq!(
interpret(&format!("json:parse('{JSON}') as [map]")),
Err(Error::Runtime(RuntimeError::ConversionImpossible {
value: json_value,
target_type: Type::List(Box::new(Type::Map))
from: json_value.r#type().unwrap(),
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
}
}))
)
}