Skip to main content

uni_common/api/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2024-2026 Dragonscale Team
3
4use std::path::PathBuf;
5use thiserror::Error;
6
7#[derive(Debug, Error)]
8#[non_exhaustive]
9pub enum UniError {
10    #[error("Database not found: {path}")]
11    NotFound { path: PathBuf },
12
13    #[error("Schema error: {message}")]
14    Schema { message: String },
15
16    #[error("Parse error: {message}")]
17    Parse {
18        message: String,
19        position: Option<usize>,
20        line: Option<usize>,
21        column: Option<usize>,
22        context: Option<String>,
23    },
24
25    #[error("Query error: {message}")]
26    Query {
27        message: String,
28        query: Option<String>,
29    },
30
31    #[error("Transaction error: {message}")]
32    Transaction { message: String },
33
34    #[error("Transaction conflict: {message}")]
35    TransactionConflict { message: String },
36
37    #[error("Transaction already completed")]
38    TransactionAlreadyCompleted,
39
40    /// Operation not supported on read-only database
41    #[error("Operation '{operation}' not supported on read-only database")]
42    ReadOnly { operation: String },
43
44    /// Label not found in schema
45    #[error("Label '{label}' not found in schema")]
46    LabelNotFound { label: String },
47
48    /// Edge type not found in schema
49    #[error("Edge type '{edge_type}' not found in schema")]
50    EdgeTypeNotFound { edge_type: String },
51
52    /// Property not found on node/edge
53    #[error("Property '{property}' not found on {entity_type} with label '{label}'")]
54    PropertyNotFound {
55        property: String,
56        entity_type: String, // "node" or "edge"
57        label: String,
58    },
59
60    /// Index not found
61    #[error("Index '{index}' not found")]
62    IndexNotFound { index: String },
63
64    /// Snapshot not found
65    #[error("Snapshot '{snapshot_id}' not found")]
66    SnapshotNotFound { snapshot_id: String },
67
68    /// Query memory limit exceeded
69    #[error("Query exceeded memory limit of {limit_bytes} bytes")]
70    MemoryLimitExceeded { limit_bytes: usize },
71
72    #[error("Database is locked by another process")]
73    DatabaseLocked,
74
75    #[error("Operation timed out after {timeout_ms}ms")]
76    Timeout { timeout_ms: u64 },
77
78    #[error("Type error: expected {expected}, got {actual}")]
79    Type { expected: String, actual: String },
80
81    #[error("Constraint violation: {message}")]
82    Constraint { message: String },
83
84    #[error("Storage error: {message}")]
85    Storage {
86        message: String,
87        #[source]
88        source: Option<Box<dyn std::error::Error + Send + Sync>>,
89    },
90
91    #[error("IO error: {0}")]
92    Io(#[from] std::io::Error),
93
94    #[error("Internal error: {0}")]
95    Internal(#[from] anyhow::Error),
96
97    #[error("Invalid identifier '{name}': {reason}")]
98    InvalidIdentifier { name: String, reason: String },
99
100    #[error("Label '{label}' already exists")]
101    LabelAlreadyExists { label: String },
102
103    #[error("Edge type '{edge_type}' already exists")]
104    EdgeTypeAlreadyExists { edge_type: String },
105
106    #[error("Permission denied: {action}")]
107    PermissionDenied { action: String },
108
109    #[error("Argument '{arg}' is invalid: {message}")]
110    InvalidArgument { arg: String, message: String },
111}
112
113pub type Result<T> = std::result::Result<T, UniError>;