hyperlight_common/flatbuffer_wrappers/
guest_error.rs

1/*
2Copyright 2025  The Hyperlight Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17extern crate flatbuffers;
18
19use alloc::string::{String, ToString};
20use alloc::vec::Vec;
21
22use anyhow::{Error, Result};
23use flatbuffers::size_prefixed_root;
24#[cfg(feature = "tracing")]
25use tracing::{Span, instrument};
26
27use crate::flatbuffers::hyperlight::generated::{
28    ErrorCode as FbErrorCode, GuestError as FbGuestError, GuestErrorArgs,
29};
30
31#[derive(Debug, Clone, Copy, Eq, PartialEq)]
32#[repr(C)]
33/// `ErrorCode` represents an error that occurred in the Hyperlight Guest.
34pub enum ErrorCode {
35    NoError = 0,
36    UnsupportedParameterType = 2,
37    GuestFunctionNameNotProvided = 3,
38    GuestFunctionNotFound = 4,
39    GuestFunctionIncorrecNoOfParameters = 5,
40    GispatchFunctionPointerNotSet = 6,
41    OutbError = 7,
42    UnknownError = 8,
43    StackOverflow = 9,
44    GsCheckFailed = 10,
45    TooManyGuestFunctions = 11,
46    FailureInDlmalloc = 12,
47    MallocFailed = 13,
48    GuestFunctionParameterTypeMismatch = 14,
49    GuestError = 15,
50    ArrayLengthParamIsMissing = 16,
51}
52
53impl From<ErrorCode> for FbErrorCode {
54    fn from(error_code: ErrorCode) -> Self {
55        match error_code {
56            ErrorCode::NoError => Self::NoError,
57            ErrorCode::UnsupportedParameterType => Self::UnsupportedParameterType,
58            ErrorCode::GuestFunctionNameNotProvided => Self::GuestFunctionNameNotProvided,
59            ErrorCode::GuestFunctionNotFound => Self::GuestFunctionNotFound,
60            ErrorCode::GuestFunctionIncorrecNoOfParameters => {
61                Self::GuestFunctionIncorrecNoOfParameters
62            }
63            ErrorCode::GispatchFunctionPointerNotSet => Self::GispatchFunctionPointerNotSet,
64            ErrorCode::OutbError => Self::OutbError,
65            ErrorCode::UnknownError => Self::UnknownError,
66            ErrorCode::StackOverflow => Self::StackOverflow,
67            ErrorCode::GsCheckFailed => Self::GsCheckFailed,
68            ErrorCode::TooManyGuestFunctions => Self::TooManyGuestFunctions,
69            ErrorCode::FailureInDlmalloc => Self::FailureInDlmalloc,
70            ErrorCode::MallocFailed => Self::MallocFailed,
71            ErrorCode::GuestFunctionParameterTypeMismatch => {
72                Self::GuestFunctionParameterTypeMismatch
73            }
74            ErrorCode::GuestError => Self::GuestError,
75            ErrorCode::ArrayLengthParamIsMissing => Self::ArrayLengthParamIsMissing,
76        }
77    }
78}
79
80impl From<FbErrorCode> for ErrorCode {
81    fn from(error_code: FbErrorCode) -> Self {
82        match error_code {
83            FbErrorCode::NoError => Self::NoError,
84            FbErrorCode::UnsupportedParameterType => Self::UnsupportedParameterType,
85            FbErrorCode::GuestFunctionNameNotProvided => Self::GuestFunctionNameNotProvided,
86            FbErrorCode::GuestFunctionNotFound => Self::GuestFunctionNotFound,
87            FbErrorCode::GuestFunctionIncorrecNoOfParameters => {
88                Self::GuestFunctionIncorrecNoOfParameters
89            }
90            FbErrorCode::GispatchFunctionPointerNotSet => Self::GispatchFunctionPointerNotSet,
91            FbErrorCode::OutbError => Self::OutbError,
92            FbErrorCode::StackOverflow => Self::StackOverflow,
93            FbErrorCode::GsCheckFailed => Self::GsCheckFailed,
94            FbErrorCode::TooManyGuestFunctions => Self::TooManyGuestFunctions,
95            FbErrorCode::FailureInDlmalloc => Self::FailureInDlmalloc,
96            FbErrorCode::MallocFailed => Self::MallocFailed,
97            FbErrorCode::GuestFunctionParameterTypeMismatch => {
98                Self::GuestFunctionParameterTypeMismatch
99            }
100            FbErrorCode::GuestError => Self::GuestError,
101            FbErrorCode::ArrayLengthParamIsMissing => Self::ArrayLengthParamIsMissing,
102            _ => Self::UnknownError,
103        }
104    }
105}
106
107impl From<u64> for ErrorCode {
108    fn from(error_code: u64) -> Self {
109        match error_code {
110            0 => Self::NoError,
111            2 => Self::UnsupportedParameterType,
112            3 => Self::GuestFunctionNameNotProvided,
113            4 => Self::GuestFunctionNotFound,
114            5 => Self::GuestFunctionIncorrecNoOfParameters,
115            6 => Self::GispatchFunctionPointerNotSet,
116            7 => Self::OutbError,
117            8 => Self::UnknownError,
118            9 => Self::StackOverflow,
119            10 => Self::GsCheckFailed,
120            11 => Self::TooManyGuestFunctions,
121            12 => Self::FailureInDlmalloc,
122            13 => Self::MallocFailed,
123            14 => Self::GuestFunctionParameterTypeMismatch,
124            15 => Self::GuestError,
125            16 => Self::ArrayLengthParamIsMissing,
126            _ => Self::UnknownError,
127        }
128    }
129}
130
131impl From<ErrorCode> for u64 {
132    fn from(error_code: ErrorCode) -> Self {
133        match error_code {
134            ErrorCode::NoError => 0,
135            ErrorCode::UnsupportedParameterType => 2,
136            ErrorCode::GuestFunctionNameNotProvided => 3,
137            ErrorCode::GuestFunctionNotFound => 4,
138            ErrorCode::GuestFunctionIncorrecNoOfParameters => 5,
139            ErrorCode::GispatchFunctionPointerNotSet => 6,
140            ErrorCode::OutbError => 7,
141            ErrorCode::UnknownError => 8,
142            ErrorCode::StackOverflow => 9,
143            ErrorCode::GsCheckFailed => 10,
144            ErrorCode::TooManyGuestFunctions => 11,
145            ErrorCode::FailureInDlmalloc => 12,
146            ErrorCode::MallocFailed => 13,
147            ErrorCode::GuestFunctionParameterTypeMismatch => 14,
148            ErrorCode::GuestError => 15,
149            ErrorCode::ArrayLengthParamIsMissing => 16,
150        }
151    }
152}
153
154impl From<ErrorCode> for String {
155    fn from(error_code: ErrorCode) -> Self {
156        match error_code {
157            ErrorCode::NoError => "NoError".to_string(),
158            ErrorCode::UnsupportedParameterType => "UnsupportedParameterType".to_string(),
159            ErrorCode::GuestFunctionNameNotProvided => "GuestFunctionNameNotProvided".to_string(),
160            ErrorCode::GuestFunctionNotFound => "GuestFunctionNotFound".to_string(),
161            ErrorCode::GuestFunctionIncorrecNoOfParameters => {
162                "GuestFunctionIncorrecNoOfParameters".to_string()
163            }
164            ErrorCode::GispatchFunctionPointerNotSet => "GispatchFunctionPointerNotSet".to_string(),
165            ErrorCode::OutbError => "OutbError".to_string(),
166            ErrorCode::UnknownError => "UnknownError".to_string(),
167            ErrorCode::StackOverflow => "StackOverflow".to_string(),
168            ErrorCode::GsCheckFailed => "GsCheckFailed".to_string(),
169            ErrorCode::TooManyGuestFunctions => "TooManyGuestFunctions".to_string(),
170            ErrorCode::FailureInDlmalloc => "FailureInDlmalloc".to_string(),
171            ErrorCode::MallocFailed => "MallocFailed".to_string(),
172            ErrorCode::GuestFunctionParameterTypeMismatch => {
173                "GuestFunctionParameterTypeMismatch".to_string()
174            }
175            ErrorCode::GuestError => "GuestError".to_string(),
176            ErrorCode::ArrayLengthParamIsMissing => "ArrayLengthParamIsMissing".to_string(),
177        }
178    }
179}
180
181/// `GuestError` represents an error that occurred in the Hyperlight Guest.
182#[derive(Debug, Clone)]
183pub struct GuestError {
184    /// The error code.
185    pub code: ErrorCode,
186    /// The error message.
187    pub message: String,
188}
189
190impl GuestError {
191    #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))]
192    pub fn new(code: ErrorCode, message: String) -> Self {
193        Self { code, message }
194    }
195}
196
197impl TryFrom<&[u8]> for GuestError {
198    type Error = Error;
199    fn try_from(value: &[u8]) -> Result<Self> {
200        let guest_error_fb = size_prefixed_root::<FbGuestError>(value)
201            .map_err(|e| anyhow::anyhow!("Error while reading GuestError: {:?}", e))?;
202        let code = guest_error_fb.code();
203        let message = match guest_error_fb.message() {
204            Some(message) => message.to_string(),
205            None => String::new(),
206        };
207        Ok(Self {
208            code: code.into(),
209            message,
210        })
211    }
212}
213
214impl TryFrom<&GuestError> for Vec<u8> {
215    type Error = Error;
216    #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))]
217    fn try_from(value: &GuestError) -> Result<Vec<u8>> {
218        let mut builder = flatbuffers::FlatBufferBuilder::new();
219        let message = builder.create_string(&value.message);
220
221        let guest_error_fb = FbGuestError::create(
222            &mut builder,
223            &GuestErrorArgs {
224                code: value.code.into(),
225                message: Some(message),
226            },
227        );
228        builder.finish_size_prefixed(guest_error_fb, None);
229        let res = builder.finished_data().to_vec();
230
231        Ok(res)
232    }
233}
234
235impl Default for GuestError {
236    #[cfg_attr(feature = "tracing", instrument(parent = Span::current(), level= "Trace"))]
237    fn default() -> Self {
238        Self {
239            code: ErrorCode::NoError,
240            message: String::new(),
241        }
242    }
243}