Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0a5d2bc
WIP on custom errors
TheRealMorgenfrue Feb 19, 2026
5fe8552
WIP 2 on errors
TheRealMorgenfrue Feb 19, 2026
3606e94
Add custom error types handling
TheRealMorgenfrue Feb 26, 2026
e11931f
Add strum
TheRealMorgenfrue Feb 26, 2026
755a318
Upate Cargo.lock
TheRealMorgenfrue Feb 26, 2026
3c24e14
Update Cargo.lock
TheRealMorgenfrue Feb 28, 2026
f9fd9c7
Implement conversion functionality between other error types, ErrorRe…
TheRealMorgenfrue Feb 28, 2026
eab62ee
Fix Leptos version and test Leptos table gen
TheRealMorgenfrue Feb 28, 2026
e948a4b
Fix missing imports
TheRealMorgenfrue Feb 28, 2026
ed2062f
Remove old error code
TheRealMorgenfrue Feb 28, 2026
3abdded
Fix: parse errors do not have access to a triple
TheRealMorgenfrue Feb 28, 2026
eef28d1
Use new error handling backend
TheRealMorgenfrue Feb 28, 2026
4e3cf2a
Minor format! changes
TheRealMorgenfrue Feb 28, 2026
32e24af
Impl for our custom server error
TheRealMorgenfrue Feb 28, 2026
c09977e
Export our custom server error
TheRealMorgenfrue Feb 28, 2026
923df1c
Add table gen on server
TheRealMorgenfrue Feb 28, 2026
abf3567
Expand error handling frontend with the new error handling backend
TheRealMorgenfrue Feb 28, 2026
bb95b8d
Begin using new error handling system
TheRealMorgenfrue Feb 28, 2026
8ca3914
WIP 1 on tables
TheRealMorgenfrue Mar 4, 2026
a2c8151
Add type annotation
TheRealMorgenfrue Mar 5, 2026
4f9aa50
WIP on frontend table
TheRealMorgenfrue Mar 5, 2026
c44a318
Remove leptos-struct-table
TheRealMorgenfrue Mar 6, 2026
eb354e7
Fix typo
TheRealMorgenfrue Mar 6, 2026
0e3a46d
Add location tracking
TheRealMorgenfrue Mar 6, 2026
afb05f0
Use debug instead of info
TheRealMorgenfrue Mar 6, 2026
31959e8
Rename VOWLRServerError to VOWLRError
TheRealMorgenfrue Mar 6, 2026
a5894b7
Make error location an option
TheRealMorgenfrue Mar 6, 2026
3d4b229
Impl Display and extension
TheRealMorgenfrue Mar 6, 2026
3586bf7
Fix CSS
TheRealMorgenfrue Mar 6, 2026
31af6ca
Add client errors
TheRealMorgenfrue Mar 6, 2026
f8a9f9a
Refactor error log
TheRealMorgenfrue Mar 6, 2026
a3d14e4
Cleanup
TheRealMorgenfrue Mar 6, 2026
43ed575
Refactor export menu to use new error handling system
TheRealMorgenfrue Mar 6, 2026
7c4e180
Remove severity description
TheRealMorgenfrue Mar 9, 2026
df23393
Allow deprecated warn
TheRealMorgenfrue Mar 9, 2026
a8355b3
Clippy fixes
TheRealMorgenfrue Mar 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@
"webgl",
], git="https://github.com/WebVOWL/WasmGrapher"}
horned-owl={git="https://github.com/phillord/horned-owl", rev="c4f7835ecae70b5e7281dc23b9b7fc6daa497f1d"}
leptos={version="0.8.16", features=["nightly", "multipart", "rkyv"]}
log="0.4"
rdf-fusion="0.1.0"
rkyv="0.8.12"
smallvec={version="1.15.1", features=["union"]}
strum={version="0.27", features=["derive"]}
tokio="1.48.0"

[dependencies]
Expand All @@ -67,16 +69,16 @@
futures={workspace=true}
getrandom={version="0.3", features=["wasm_js"]}
gloo-timers="0.2"
grapher={workspace=true}
grapher.workspace=true
http={version="1.3.1", optional=true}
leptos={version="0.8.16", features=["nightly", "multipart", "rkyv"]}
leptos.workspace=true
leptos_actix={version="0.8.7", optional=true}
leptos_meta={version="0.8.6"}
leptos_router={version="0.8.12", features=["nightly"]}
log={workspace=true}
log.workspace=true
rayon="1.10"
reqwest={version="0.12.24", optional=true, features=["json", "stream"]}
rkyv={workspace=true}
rkyv.workspace=true
tokio={workspace=true, optional=true}
vowlr-database={path="crates/database", optional=true}
vowlr-parser={path="crates/parser", optional=true}
Expand Down Expand Up @@ -113,6 +115,7 @@
"HtmlInputElement",
"HtmlCollection",
"Blob",
"BlobPropertyBag",
]


Expand All @@ -127,6 +130,7 @@
"dep:vowlr-database",
"dep:vowlr-parser",
"leptos-use/actix",
"vowlr-util/server",
]
ssr=[
"dep:actix-files",
Expand Down
73 changes: 73 additions & 0 deletions crates/database/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::panic::Location;

use crate::serializers::Triple;
use oxrdf::{BlankNodeIdParseError, IriParseError};
use vowlr_util::prelude::{ErrorRecord, ErrorSeverity, ErrorType};

#[derive(Debug)]
pub enum SerializationErrorKind {
/// An error raised when the object of a triple is required but missing.
MissingObject(Triple, String),
/// An error raised when the subject of a triple is required but missing.
MissingSubject(Triple, String),
/// An error raised when the serializer encountered an unrecoverable problem.
SerializationFailed(Triple, String),
/// An error raised during Iri or IriRef validation.
IriParseError(String, IriParseError),
/// An error raised during BlankNode IDs validation
BlankNodeParseError(String, BlankNodeIdParseError),
}

#[derive(Debug)]
pub struct SerializationError {
/// The contained error type.
inner: SerializationErrorKind,
/// The error's location in the source code.
location: &'static Location<'static>,
}
impl std::fmt::Display for SerializationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.inner)
}
}

impl From<SerializationErrorKind> for SerializationError {
#[track_caller]
fn from(error: SerializationErrorKind) -> Self {
SerializationError {
inner: error,
location: Location::caller(),
}
}
}

impl From<SerializationError> for ErrorRecord {
fn from(value: SerializationError) -> Self {
let (message, severity) = match value.inner {
SerializationErrorKind::MissingObject(triple, e) => {
(format!("{e}:\n{triple}"), ErrorSeverity::Warning)
}
SerializationErrorKind::MissingSubject(triple, e) => {
(format!("{e}:\n{triple}"), ErrorSeverity::Warning)
}
SerializationErrorKind::SerializationFailed(triple, e) => {
(format!("{e}:\n{triple}"), ErrorSeverity::Critical)
}
SerializationErrorKind::IriParseError(iri, iri_parse_error) => (
format!("{iri_parse_error} (IRI: {iri})"),
ErrorSeverity::Error,
),
SerializationErrorKind::BlankNodeParseError(id, blank_node_id_parse_error) => (
format!("{blank_node_id_parse_error} (ID: {id})"),
ErrorSeverity::Error,
),
};
ErrorRecord::new(
severity,
ErrorType::Serializer,
message,
#[cfg(debug_assertions)]
Some(value.location.to_string()),
)
}
}
99 changes: 1 addition & 98 deletions crates/database/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
use std::fmt::{Display, Formatter};

use grapher::prelude::{ElementType, OwlEdge, OwlType, RdfEdge, RdfType};
use oxrdf::{BlankNodeIdParseError, IriParseError};
use vowlr_parser::errors::VOWLRStoreError;

use crate::serializers::Triple;

mod errors;
pub mod serializers;
pub mod store;
pub mod vocab;
Expand All @@ -16,93 +9,3 @@ pub mod prelude {

pub use crate::store::VOWLRStore;
}

pub const SYMMETRIC_EDGE_TYPES: [ElementType; 1] =
[ElementType::Owl(OwlType::Edge(OwlEdge::DisjointWith))];

pub const PROPERTY_EDGE_TYPES: [ElementType; 7] = [
ElementType::Owl(OwlType::Edge(OwlEdge::ObjectProperty)),
ElementType::Owl(OwlType::Edge(OwlEdge::DatatypeProperty)),
ElementType::Owl(OwlType::Edge(OwlEdge::DeprecatedProperty)),
ElementType::Owl(OwlType::Edge(OwlEdge::ExternalProperty)),
ElementType::Owl(OwlType::Edge(OwlEdge::ValuesFrom)),
ElementType::Owl(OwlType::Edge(OwlEdge::InverseOf)),
ElementType::Rdf(RdfType::Edge(RdfEdge::RdfProperty)),
];

pub trait SerializationErrorExt {
fn triple(&self) -> Option<&Triple>;
}

macro_rules! ser_err {
($variant:ident($triple:expr, $msg:expr)) => {
$crate::SerializationErrorKind::$variant(($triple).map(Box::new), $msg)
};
}
pub(crate) use ser_err;

#[derive(Debug)]
pub enum SerializationErrorKind {
MissingObject(Option<Box<Triple>>, String),
MissingSubject(Option<Box<Triple>>, String),
SerializationFailed(Option<Box<Triple>>, String),
IriParseError(Option<Box<Triple>>, Box<IriParseError>),
BlankNodeParseError(Option<Box<Triple>>, Box<BlankNodeIdParseError>),
}
impl SerializationErrorExt for SerializationErrorKind {
fn triple(&self) -> Option<&Triple> {
match &self {
SerializationErrorKind::MissingObject(triple, _)
| SerializationErrorKind::MissingSubject(triple, _)
| SerializationErrorKind::SerializationFailed(triple, _)
| SerializationErrorKind::IriParseError(triple, _)
| SerializationErrorKind::BlankNodeParseError(triple, _) => {
triple.as_ref().map(|t| &**t)
}
}
}
}

#[derive(Debug)]
pub struct SerializationError {
inner: SerializationErrorKind,
}
impl Display for SerializationError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "SerializationError: {:?}", self.inner)
}
}

impl SerializationErrorExt for SerializationError {
fn triple(&self) -> Option<&Triple> {
self.inner.triple()
}
}

impl From<SerializationErrorKind> for SerializationError {
fn from(error: SerializationErrorKind) -> Self {
SerializationError { inner: error }
}
}

impl From<IriParseError> for SerializationError {
fn from(error: IriParseError) -> Self {
SerializationError {
inner: SerializationErrorKind::IriParseError(None, Box::new(error)),
}
}
}

impl From<SerializationError> for VOWLRStoreError {
fn from(error: SerializationError) -> Self {
VOWLRStoreError::from(error.to_string())
}
}

impl From<BlankNodeIdParseError> for SerializationError {
fn from(error: BlankNodeIdParseError) -> Self {
SerializationError {
inner: SerializationErrorKind::BlankNodeParseError(None, Box::new(error)),
}
}
}
28 changes: 7 additions & 21 deletions crates/database/src/serializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use std::{
use grapher::prelude::{ElementType, GraphDisplayData, OwlEdge, OwlType};
use log::error;
use oxrdf::Term;
use vowlr_util::prelude::ErrorRecord;

use crate::{PROPERTY_EDGE_TYPES, SYMMETRIC_EDGE_TYPES};
use crate::serializers::util::{PROPERTY_EDGE_TYPES, SYMMETRIC_EDGE_TYPES};

pub mod frontend;
pub mod util;
Expand Down Expand Up @@ -221,15 +222,8 @@ pub struct SerializationDataBuffer {
/// can be either the subject, object or both (in this case, subject is used)
/// - Value = The unresolved triples.
unknown_buffer: HashMap<Term, HashSet<Triple>>,
/// Stores triples that are impossible to serialize.
///
/// This could be caused by various reasons, such as
/// visualization of the triple is not supported.
///
/// Each element is a tuple of:
/// - 0 = The triple (if any).
/// - 1 = The reason it failed to serialize (or the message if no triple is available).
failed_buffer: Vec<(Option<Triple>, String)>,
/// Stores errors encountered during serialization.
failed_buffer: Vec<ErrorRecord>,
/// The base IRI of the document.
///
/// For instance: `http://purl.obolibrary.org/obo/envo.owl`
Expand Down Expand Up @@ -409,17 +403,9 @@ impl Display for SerializationDataBuffer {
.join("\n")
)?;
}
writeln!(f, "\tfailed_buffer:")?;
for (triple, reason) in self.failed_buffer.iter() {
match triple {
Some(triple) => {
writeln!(f, "\t\t{} : {}", triple, reason)?;
}
None => {
writeln!(f, "\t\tNO TRIPLE : {}", reason)?;
}
}
}
// Not needed as it's displayed by the serializer
// writeln!(f, "\tfailed_buffer:")?;
// writeln!(f, "{}", ErrorRecord::format_records(&self.failed_buffer))?;
writeln!(f, "}}")
}
}
Expand Down
Loading
Loading