tango_client/
error.rs

1//! Error types used with Tango.
2
3use std::error;
4use std::fmt;
5use std::ptr;
6
7use crate::c;
8use crate::types::{ErrSeverity, string_from};
9
10/// Convenience alias for a Result from Tango APIs.
11pub type TangoResult<R> = Result<R, TangoError>;
12
13
14/// Represents a single "entry" of a Tango error stack.
15#[derive(Debug)]
16pub struct TangoFailure {
17    pub desc: String,
18    pub reason: String,
19    pub origin: String,
20    pub severity: ErrSeverity,
21}
22
23/// A Tango error; corresponds to an exception thrown by the C++ API.
24#[derive(Debug)]
25pub struct TangoError {
26    pub failures: Vec<TangoFailure>,
27}
28
29impl fmt::Display for TangoError {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        write!(f, "TangoError[\n")?;
32        for fail in &self.failures {
33            write!(f, "DevFailed[\n")?;
34            write!(f, "      desc = {}\n", fail.desc)?;
35            write!(f, "    origin = {}\n", fail.origin)?;
36            write!(f, "    reason = {}\n", fail.reason)?;
37            write!(f, "  severity = {:?}]\n\n", fail.severity)?;
38        }
39        write!(f, "]\n")
40    }
41}
42
43impl error::Error for TangoError {
44    fn description(&self) -> &str {
45        if self.failures.is_empty() {
46            ""
47        } else {
48            &self.failures[0].desc
49        }
50    }
51}
52
53impl TangoError {
54    pub(crate) fn from_stack(stackptr: *mut c::ErrorStack) -> TangoError {
55        let stack = unsafe  { *stackptr };
56        let mut seq = Vec::with_capacity(stack.length as usize);
57        for i in 0..stack.length {
58            unsafe {
59                let df = ptr::read(stack.sequence.offset(i as isize));
60                let fail = TangoFailure {
61                    desc: string_from(df.desc),
62                    reason: string_from(df.reason),
63                    origin: string_from(df.origin),
64                    severity: ErrSeverity::from_c(df.severity)
65                };
66                seq.push(fail);
67            }
68        }
69        unsafe { c::tango_free_ErrorStack(stackptr); }
70        TangoError { failures: seq }
71    }
72}