import tor package
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// SPDX-FileCopyrightText: 2023 Foundation Devices Inc.
|
||||
// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use log::{error, warn};
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::ffi::{c_char, CString};
|
||||
//pub(crate) use crate::unwrap_or_return;
|
||||
|
||||
thread_local! {
|
||||
static LAST_ERROR: RefCell<Option<Box<dyn Error>>> = RefCell::new(None);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tor_last_error_message() -> *const c_char {
|
||||
let last_error = match crate::error::take_last_error() {
|
||||
Some(err) => err,
|
||||
None => return CString::new("").unwrap().into_raw(),
|
||||
};
|
||||
|
||||
let error_message = last_error.to_string();
|
||||
CString::new(error_message).unwrap().into_raw()
|
||||
}
|
||||
|
||||
macro_rules! unwrap_or_return {
|
||||
($a:expr,$b:expr) => {
|
||||
match $a {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
update_last_error(e);
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Update the most recent error, clearing whatever may have been there before.
|
||||
pub fn update_last_error<E: Error + 'static>(err: E) {
|
||||
error!("Setting LAST_ERROR: {}", err);
|
||||
|
||||
{
|
||||
// Print a pseudo-backtrace for this error, following back each error's
|
||||
// cause until we reach the root error.
|
||||
let mut cause = err.source();
|
||||
while let Some(parent_err) = cause {
|
||||
warn!("Caused by: {}", parent_err);
|
||||
cause = parent_err.source();
|
||||
}
|
||||
}
|
||||
|
||||
LAST_ERROR.with(|prev| {
|
||||
*prev.borrow_mut() = Some(Box::new(err));
|
||||
});
|
||||
}
|
||||
|
||||
/// Retrieve the most recent error, clearing it in the process.
|
||||
pub fn take_last_error() -> Option<Box<dyn Error>> {
|
||||
LAST_ERROR.with(|prev| prev.borrow_mut().take())
|
||||
}
|
||||
Reference in New Issue
Block a user