dusk_vm/error.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use dusk_core::TxPreconditionError;
8use dusk_core::transfer::PANIC_NONCE_NOT_READY;
9use piecrust::Error;
10
11/// Errors that can occur during transaction execution in the VM.
12///
13/// This enum encapsulates different types of errors that may arise, including
14/// precondition failures, unspendable errors, and failed refunds.
15/// Each variant provides context about the nature of the error, allowing for
16/// more precise error handling and debugging.
17#[derive(Debug, thiserror::Error)]
18pub enum ExecutionError {
19 /// Occurs when a refund operation fails after transaction execution.
20 #[error("Failed refund: {0}")]
21 FailedRefund(Error),
22
23 /// Occurs when the transaction is valid but cannot be processed at the
24 /// moment, like when the nonce used is not the next one
25 #[error("Nonce not ready to be used yet")]
26 NotReady,
27
28 /// Occurs when a precondition for transaction execution is not met.
29 #[error("Precondition error: {0}")]
30 Precondition(String),
31
32 /// Occurs when a transaction is deemed unspendable due to an error during
33 /// execution.
34 #[error("Unspendable: {0}")]
35 Unspendable(Error),
36}
37
38impl ExecutionError {
39 /// Creates a new `ExecutionError` with the `Precondition` variant.
40 pub fn precondition<T: ToString>(msg: T) -> Self {
41 Self::Precondition(msg.to_string())
42 }
43
44 /// Creates a new `ExecutionError` from an existing `Error` happening during
45 /// the spend_or_execute phase, categorizing it as `Unspendable` unless it's
46 /// a specific nonce not ready panic.
47 pub fn from_spend_and_execute(inner: Error) -> Self {
48 if let Error::Panic(val) = &inner
49 && val == PANIC_NONCE_NOT_READY
50 {
51 Self::NotReady
52 } else {
53 Self::Unspendable(inner)
54 }
55 }
56 /// Creates a new `ExecutionError` with the `FailedRefund` variant.
57 pub fn failed_refund(inner: Error) -> Self {
58 Self::FailedRefund(inner)
59 }
60}
61
62impl From<TxPreconditionError> for ExecutionError {
63 fn from(err: TxPreconditionError) -> Self {
64 ExecutionError::Precondition(err.legacy_to_string())
65 }
66}