use boltr::error::BoltError;
use kglite::api::{KgError, KgErrorCode};
pub fn kg_to_bolt(err: KgError) -> BoltError {
let code = neo4j_status_code(err.code());
BoltError::Query {
code: code.into(),
message: err.to_string(),
}
}
fn neo4j_status_code(code: KgErrorCode) -> &'static str {
match code {
KgErrorCode::CypherSyntax => "Neo.ClientError.Statement.SyntaxError",
KgErrorCode::CypherTimeout => "Neo.ClientError.Transaction.TransactionTimedOut",
KgErrorCode::CypherTypeMismatch => "Neo.ClientError.Statement.TypeError",
KgErrorCode::CypherExecution => "Neo.DatabaseError.Statement.ExecutionFailed",
KgErrorCode::Schema => "Neo.ClientError.Schema.ConstraintValidationFailed",
KgErrorCode::Validation | KgErrorCode::Expr => "Neo.ClientError.Statement.ArgumentError",
KgErrorCode::NodeNotFound
| KgErrorCode::ConnectionNotFound
| KgErrorCode::PropertyNotFound => "Neo.ClientError.Statement.EntityNotFound",
KgErrorCode::InvalidArgument => "Neo.ClientError.Statement.ArgumentError",
KgErrorCode::MissingArgument => "Neo.ClientError.Statement.ParameterMissing",
KgErrorCode::FileNotFound
| KgErrorCode::FileFormat
| KgErrorCode::FileIo
| KgErrorCode::Internal => "Neo.DatabaseError.General.UnknownError",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn syntax_error_maps_to_neo_clienterror_statement_syntaxerror() {
let err = KgError::CypherSyntax {
message: "unexpected token 'NOT'".into(),
line: Some(1),
col: Some(7),
};
let bolt = kg_to_bolt(err);
match bolt {
BoltError::Query { code, .. } => {
assert_eq!(code, "Neo.ClientError.Statement.SyntaxError");
}
other => panic!("expected Query, got {other:?}"),
}
}
#[test]
fn every_code_has_a_neo4j_string_starting_with_neo_dot() {
for code in [
KgErrorCode::CypherSyntax,
KgErrorCode::CypherTimeout,
KgErrorCode::CypherExecution,
KgErrorCode::CypherTypeMismatch,
KgErrorCode::Schema,
KgErrorCode::Validation,
KgErrorCode::Expr,
KgErrorCode::NodeNotFound,
KgErrorCode::ConnectionNotFound,
KgErrorCode::PropertyNotFound,
KgErrorCode::FileNotFound,
KgErrorCode::FileFormat,
KgErrorCode::FileIo,
KgErrorCode::InvalidArgument,
KgErrorCode::MissingArgument,
KgErrorCode::Internal,
] {
let s = neo4j_status_code(code);
assert!(
s.starts_with("Neo."),
"code {:?} mapped to non-Neo.* string: {}",
code,
s
);
assert_eq!(
s.split('.').count(),
4,
"code {:?} mapped to wrong-shaped string: {} (want 4 dotted segments)",
code,
s
);
}
}
}