Line data Source code
1 : //! Errors of the core.
2 :
3 : use dashql_buffers::status::StatusCode;
4 : use std::fmt;
5 :
6 : /// An error, either a status code or an invalid argument
7 : #[derive(Clone, Debug, PartialEq)]
8 : pub struct Error {
9 : /// The status code, None for invalid arguments
10 : pub status: Option<StatusCode>,
11 : /// The error message, the variant name of the status code for status errors
12 : pub message: String,
13 : }
14 :
15 : pub type Result<T> = std::result::Result<T, Error>;
16 :
17 : impl Error {
18 58 : pub fn status(status: StatusCode) -> Self {
19 58 : Self {
20 58 : status: Some(status),
21 58 : message: status.variant_name().unwrap_or("").to_string(),
22 58 : }
23 58 : }
24 :
25 72 : pub fn invalid_argument(message: impl Into<String>) -> Self {
26 72 : Self {
27 72 : status: None,
28 72 : message: message.into(),
29 72 : }
30 72 : }
31 :
32 : /// The user-facing message: the default message of the status code, or the message of other
33 : /// errors
34 29 : pub fn what(&self) -> &str {
35 29 : match self.status {
36 25 : Some(status) => default_message(status),
37 4 : None => &self.message,
38 : }
39 29 : }
40 : }
41 :
42 : /// The default message of a status code
43 48 : pub fn default_message(status: StatusCode) -> &'static str {
44 48 : match status {
45 2 : StatusCode::CATALOG_NULL => "Catalog is null",
46 2 : StatusCode::CATALOG_MISMATCH => "Catalog is not matching",
47 2 : StatusCode::CATALOG_ID_OUT_OF_SYNC => "Catalog id is out of sync",
48 3 : StatusCode::SCRIPT_NOT_PARSED => "Script is not parsed",
49 2 : StatusCode::SCRIPT_NOT_ANALYZED => "Script is not analyzed",
50 2 : StatusCode::SCRIPT_BUSY => "Script has an active asynchronous analysis job",
51 2 : StatusCode::CATALOG_SCRIPT_NOT_ANALYZED => "Unanalyzed scripts cannot be added to the catalog",
52 2 : StatusCode::CATALOG_SCRIPT_UNKNOWN => "Script is missing in catalog",
53 2 : StatusCode::CATALOG_DESCRIPTOR_POOL_UNKNOWN => "Schema descriptor pool is not known",
54 2 : StatusCode::CATALOG_DESCRIPTOR_TABLES_NULL => "Schema descriptor field `tables` is null or empty",
55 2 : StatusCode::CATALOG_DESCRIPTOR_TABLE_NAME_EMPTY => "Table name in schema descriptor is null or empty",
56 2 : StatusCode::CATALOG_DESCRIPTOR_TABLE_NAME_COLLISION => "Schema descriptor contains a duplicate table name",
57 2 : StatusCode::COMPLETION_MISSES_CURSOR => "Completion requires a script cursor",
58 2 : StatusCode::COMPLETION_MISSES_SCANNER_TOKEN => "Completion requires a scanner token",
59 2 : StatusCode::COMPLETION_STATE_INCOMPATIBLE => "Completion state is incompatible",
60 2 : StatusCode::COMPLETION_STRATEGY_UNKNOWN => "Completion strategy is unknown",
61 2 : StatusCode::COMPLETION_WITHOUT_CONTINUATION => "Completion has no continuation",
62 2 : StatusCode::COMPLETION_CANDIDATE_INVALID => "Completion candidate is invalid",
63 2 : StatusCode::COMPLETION_CATALOG_OBJECT_INVALID => "Completion catalog object is invalid",
64 2 : StatusCode::COMPLETION_TEMPLATE_INVALID => "Completion template is invalid",
65 2 : StatusCode::EXTERNAL_ID_COLLISION => "Collision on external identifier",
66 2 : StatusCode::VIEWMODEL_INPUT_JSON_PARSER_ERROR => "Failed to parse JSON for ViewModel",
67 2 : StatusCode::OK => "",
68 1 : _ => "Unknown error",
69 : }
70 48 : }
71 :
72 : impl fmt::Display for Error {
73 2 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 2 : f.write_str(&self.message)
75 2 : }
76 : }
77 :
78 : impl std::error::Error for Error {}
|