Skip to main content

leo_errors/errors/
mod.rs

1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17/// The LeoError type that contains all sub error types.
18/// This allows a unified error type throughout the Leo crates.
19#[derive(Debug, Error)]
20pub enum LeoError {
21    #[error(transparent)]
22    Formatted(#[from] crate::Formatted),
23    #[error(transparent)]
24    Backtraced(#[from] crate::Backtraced),
25    #[error("")]
26    LastErrorCode(i32),
27    #[error(transparent)]
28    SnarkVM(#[from] anyhow::Error),
29}
30
31impl LeoError {
32    pub fn error_code(&self) -> String {
33        use LeoError::*;
34        match self {
35            Formatted(e) => e.error_code(),
36            Backtraced(e) => e.error_code(),
37            LastErrorCode(_) => unreachable!(),
38            SnarkVM(_) => "SnarkVM Error".to_string(),
39        }
40    }
41
42    pub fn exit_code(&self) -> i32 {
43        use LeoError::*;
44        match self {
45            Formatted(e) => e.exit_code(),
46            Backtraced(e) => e.exit_code(),
47            LastErrorCode(code) => *code,
48            SnarkVM(_) => 11000,
49        }
50    }
51
52    /// Borrow a structured, LSP-agnostic view of this error.
53    ///
54    /// Only [`LeoError::Formatted`] variants carry a span and labeled
55    /// secondary information, so other variants return `None`. The caller is
56    /// expected to fall back to a synthetic package-level diagnostic in that
57    /// case; see the `leo-lsp` diagnostics module for an example.
58    ///
59    /// [`LeoError::LastErrorCode`] is a sentinel used to signal that an error
60    /// has already been emitted through a handler. It deliberately returns
61    /// `None` so it is never published as a separate diagnostic.
62    pub fn diagnostic_view(&self) -> Option<crate::DiagnosticView<'_>> {
63        match self {
64            LeoError::Formatted(formatted) => Some(formatted.diagnostic_view()),
65            LeoError::Backtraced(_) | LeoError::LastErrorCode(_) | LeoError::SnarkVM(_) => None,
66        }
67    }
68
69    /// Return whether this error is the sentinel raised after a handler emit.
70    ///
71    /// `Handler::last_err` produces [`LeoError::LastErrorCode`] when the
72    /// emitter has already buffered a real diagnostic. Consumers should skip
73    /// the sentinel when collecting structured diagnostics so the original
74    /// error is published exactly once.
75    pub fn is_last_error_code(&self) -> bool {
76        matches!(self, LeoError::LastErrorCode(_))
77    }
78}
79
80/// The LeoWarning type that contains all sub warning types.
81#[derive(Debug, Error)]
82pub enum LeoWarning {
83    #[error(transparent)]
84    Formatted(#[from] crate::Formatted),
85}
86
87impl LeoWarning {
88    pub fn error_code(&self) -> String {
89        use LeoWarning::*;
90        match self {
91            Formatted(w) => w.warning_code(),
92        }
93    }
94
95    /// Borrow a structured, LSP-agnostic view of this warning.
96    ///
97    /// Every variant currently wraps a [`Formatted`] payload, so the view is
98    /// always available. The signature is kept symmetric with
99    /// [`LeoError::diagnostic_view`] so future variants that lack span data
100    /// can opt out without breaking call sites.
101    pub fn diagnostic_view(&self) -> Option<crate::DiagnosticView<'_>> {
102        match self {
103            LeoWarning::Formatted(formatted) => Some(formatted.diagnostic_view()),
104        }
105    }
106}
107
108/// A global result type for all Leo crates, that defaults the errors to be a LeoError.
109pub type Result<T, E = LeoError> = core::result::Result<T, E>;