lightgbm3/
error.rs

1//! Functionality related to errors and error handling.
2
3use std::{
4    error,
5    ffi::CStr,
6    fmt::{self, Debug, Display},
7};
8
9#[cfg(feature = "polars")]
10use polars::prelude::*;
11
12/// Convenience return type for most operations which can return an `LightGBM`.
13pub type Result<T> = std::result::Result<T, Error>;
14
15/// Wrap errors returned by the LightGBM library.
16#[derive(Debug, Eq, PartialEq)]
17pub struct Error {
18    desc: String,
19}
20
21impl Error {
22    pub(crate) fn new<S: Into<String>>(desc: S) -> Self {
23        Self { desc: desc.into() }
24    }
25
26    /// Check the return value from an LightGBM FFI call, and return the last error message on error.
27    ///
28    /// Return values of 0 are treated as success, returns values of -1 are treated as errors.
29    ///
30    /// Meaning of any other return values are undefined, and will cause a panic.
31    pub(crate) fn check_return_value(ret_val: i32) -> Result<()> {
32        match ret_val {
33            0 => Ok(()),
34            -1 => Err(Self::from_lightgbm()),
35            _ => panic!("unexpected return value '{}', expected 0 or -1", ret_val),
36        }
37    }
38
39    /// Get the last error message from LightGBM.
40    fn from_lightgbm() -> Self {
41        let c_str = unsafe { CStr::from_ptr(lightgbm3_sys::LGBM_GetLastError()) };
42        let str_slice = c_str.to_str().unwrap();
43        Self::new(str_slice)
44    }
45}
46
47impl error::Error for Error {}
48
49impl Display for Error {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        write!(f, "LightGBM error: {}", &self.desc)
52    }
53}
54
55#[cfg(feature = "polars")]
56impl From<PolarsError> for Error {
57    fn from(pe: PolarsError) -> Self {
58        Self {
59            desc: pe.to_string(),
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn return_value_handling() {
70        let result = Error::check_return_value(0);
71        assert_eq!(result, Ok(()));
72
73        let result = Error::check_return_value(-1);
74        assert_eq!(result, Err(Error::new("Everything is fine")));
75    }
76}