Clean up errors; Add more pretty errors
This commit is contained in:
parent
bda217135e
commit
fd33f330f7
@ -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!()
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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 },
|
||||
|
||||
|
12
tests/as.rs
12
tests/as.rs
@ -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
|
||||
}
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user