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 {
|
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!()
|
||||||
};
|
};
|
||||||
|
@ -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),
|
||||||
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
@ -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 },
|
||||||
|
|
||||||
|
12
tests/as.rs
12
tests/as.rs
@ -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
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user