How to convert &str to Error in fn map_err

I often use two ways as following to return error

struct UserErr(String);
impl UserErr {
  pub fn new(msg: &str)-> Self {
impl std::fmt::Display for UserErr {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>)-> Result<(), std::fmt::Error> {
     write!(f, "{}", self.0)
impl std::error::Error for UserErr {}

fn foo()-> Result<std::fs::File, Box<dyn std::error::Error>> {

  // the first method:
  let _f = std::fs::File::open("").map_err(|e| UserErr::new(&format!("User error, and original error: {}", e.to_string())))?;
 // the second method
 let f = match std::fs::File::open("") {
     Ok(f)=> f,
     Err(e)=> Err(format!("User error, and original error: {}", e.to_string()))?,


Here is playground

With the first method, I have to define a struct UserErr; And with the second method, it will unwrap f and wrap f again.
I wonder,

  1. in the second method, it looks like String format!("User error, and original error: {}", e.to_string()) was auto casted some kind of Error, so which type of Error (a struct that impl trait std::error::Error) this string auto casted ?
  2. How can I use map_err to map error to a customed string without define a new type(struct UserErr in this example)?

Any help would be appreciated, thanks.

For your first question, well, it works because of the following impl in the standard library:

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<dyn Error + Send + Sync> {
    /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
    /// # Examples
    /// ```
    /// use std::error::Error;
    /// use std::mem;
    /// let a_string_error = "a string error".to_string();
    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
    /// assert!(
    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
    /// ```
    fn from(err: String) -> Box<dyn Error + Send + Sync> {
        struct StringError(String);

        impl Error for StringError {
            fn description(&self) -> &str {

        impl Display for StringError {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                Display::fmt(&self.0, f)

        // Purposefully skip printing "StringError(..)"
        impl Debug for StringError {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                Debug::fmt(&self.0, f)


If you want to access this via map_err, then you can try calling .into() on your string. This will work if the compiler can infer the target error type.


Cool, it works! Thanks.

In this case, the compiler cannot infer the target error type. Is there a good way to implement it without defining a new error?
The code snippet is as following,

let hmap = HashMap::from([("hello", "world")]);
let _ = hmap.get("he").ok_or(format!("error").into())?;

Here is playground

The compiler complains,

26 |     let _ = hmap.get("he").ok_or(format!("error").into())?;
   |                            ^^^^^ ----------------------- this method call resolves to `T`
   |                            |
   |                            cannot infer type for type parameter `E` declared on the associated function `ok_or`

error[E0283]: type annotations needed

Expect further answer. Thanks

The question mark operator inserts a call to into of itself. Since you now have a chain of two into calls, it can't figure out what the intermediate type should be.

Remove the into call and let the question mark do it for you.


It works :+1: thanks again.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.