noib3/nvim-oxi

[Question] Handling custom errors

Closed this issue · 4 comments

Hey!

I'm not sure how to handle errors with nvim_oxi. I want to be able to create custom errors and have them as returned values in Result.

#[derive(Deserialize, Serialize)]
struct MyData {
    field_1: String,
    field_2: usize,
}

enum CustomError {
    BadError,
    VeryBadError,
}

fn can_throw_custom_error() -> oxi::Result<MyData> {
    if randint(0, 1) == 0 {
        return Err(CustomError::BadError) // <- This doesn't work because I cannot create a new type of error that fits in oxi::Result
    }
    Ok(MyData { field_1: "whatev".to_string(), field_2: 42 })
}

As written in the code, I cannot write return Err(.... The solution I am going for is to have as in the nvim_oxi crate:

use thiserror::Error as ThisError;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Clone, Debug, ThisError)]
pub enum CustomError {
    #[error(transparent)]
    Oxi(#[from] oxi::Error),
    
    #[error("This is a bad error")]
    BadError,

    #[error("This is a Very bad error")]
    VeryBadError,
}

fn can_throw_custom_error() -> Result<MyData> {...

I have a small problem with this code. I have to copy the errors in the nvim_oxi::Error enum by adding in CustomError:

    #[error(transparent)]
    Lua(#[from] oxi_luajit::Error),

    #[error(transparent)]
    Api(#[from] oxi_api::Error),

   ...

This is repetition and I don't know how to avoid it without having .map_err(|err| Into::into(err)...) every place I have a ?.

Is it the right way to do it? Is there another way where I can just use nvim_oxi::Error conversion directly?

This is repetition and I don't know how to avoid it without having .map_err(|err| Into::into(err)...) every place I have a ?

You can just use ? after a Result<T, U> in a function returning Result<T, V> as long as V implements From<U>.

Btw, this is just a Rust question that has nothing to do with this specific project, and a place like the Rust forum would more appropriate for this type of discussion.

Closing as off-topic.

In this case, it's U -> V -> W. W is CustomError, V is oxi::Error, U is mlua::Error (or any handled error by oxi::Error). I'm not sure that it's a general Rust topic as nvim_oxi handles all these errors (U) with oxi::Error but doesn't return oxi::Error. It returns mlua::Error.

It's not a huge problem because we can copy/paste the content of oxi::Error and put it in our CustomError. It feels just a bit weird.

Btw, when you close issue, I cannot reopen it.

nvim_oxi::Error is just there for convenience. There's nothing stopping you from constructing your own error type out of the variants in nvim_oxi::Error, i.e. just put mlua::Error in your CustomError.

Alright, I see. I'm using nvim_oxi for a plugin these days and it's super convenient. Thank you.