#How can I declare this struct which has an Optional error field?

20 messages · Page 1 of 1 (latest)

last temple
#

How can I declare this struct correctly?

PLAYGROUND CODE

use std::{error};

pub struct AppError {
  msg: Option<String>,
  // error: Option<anyhow::Error>, // This works
  error: Option<dyn error::Error + Send + Sync + 'static>, // but I need this, not anyhow
}

the error is:

error[E0277]: the size for values of type `(dyn std::error::Error + Send + Sync + 'static)` cannot be known at compilation time
 --> src/lib.rs:6:10
  |
6 |   error: Option<dyn error::Error + Send + Sync + 'static>, // but I need this, not anyhow
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `(dyn std::error::Error + Send + Sync + 'static)`
note: required by a bound in `Option`

For more information about this error, try `rustc --explain E0277`.

How to fix this?

SO question: https://stackoverflow.com/questions/73939213/how-can-i-declare-this-struct-which-has-an-optional-error-field.

shell salmon
#

dyn must always appear inside some pointer type, and Option is not a pointer

#

for an owned pointer, as you need here, you would use Box or Arc

#
error: Option<Box<dyn error::Error + Send + Sync + 'static>>
harsh mango
#

the trait Sized is not implemented for (dyn std::error::Error + Send + Sync + 'static)
note: required by a bound in Option

shell salmon
#

(the Option isn't actually part of the problem here, except as exactly where the problem was hit — you'd have the same results if the error wasn't optional, except that it would instead make your AppError type dynamically sized and give you trouble when you went to try to create it)

last temple
#

What do you suggest guys to have that field?

#

anyhow::Error works but I need to avoid it

shell salmon
#

I already wrote it

#
error: Option<Box<dyn error::Error + Send + Sync + 'static>>
#

note the Box inside the Option

last temple
#

Yeah I know but then I need to always use the Box if I use that struct... something like Box::new() in the code is not awesome, do you agree?

shell salmon
#

you can write a function that takes the generic error and boxes it while constructing your struct

last temple
#

mmm ok

#

I'm trying

shell salmon
#
impl AppError {
    pub fn new<E: Error + Send + Sync + 'static>(msg: Option<String>, error: Option<E>) -> Self {
        Self {
            msg,
            error: error.map(|e| Box::new(e) as _)
        }
    }
}
#

something like that

#

(the as may not be necessary; not sure; the point is to request the conversion from Box<E> to Box<dyn ...>)

#

ok, just tested and as _ suffices ("please coerce to the obvious type")

last temple