How to throw NoneError instead of unwrapping an option

    pub fn parse_id(pathbuf: &std::path::PathBuf) -> Result<u128, Box<dyn std::error::Error>> {
        Ok(pathbuf
            .file_stem()
            .unwrap() // I really don't want any panic here
            .to_string_lossy()
            .to_string()
            .trim_start_matches(|c: char| !c.is_digit(10))
            .parse()?)
    }

    fn main() {
        let pathbuf = std::path::PathBuf::from(r"/hello/world/Alarm__123.timer");
        dbg!(parse_id(&pathbuf));
    }

You can use ? on an Option precisely to return a NoneError, but NoneError does not implement the Error trait, since that trait is only implemented on errors having a meaningful description / error message, which NoneError has not.

You can "map" NoneError to a custom type, such as a string literal for a quick meaningful error message, thanks to the .ok_or_else(|| error_message)? idiom (or .ok_or(error_message) for constant error messages):

pub
fn parse_id (pathbuf: &'_ ::std::path::PathBuf)
  -> Result<
        u128,
        Box<dyn ::std::error::Error + 'static>,
    >
{Ok({
    pathbuf
        .file_stem()
        .ok_or("No filename to extract the stem from")?
        .to_string_lossy()
        .to_string() // not needed
        .trim_start_matches(|c: char| !c.is_digit(10))
        .parse()?
})}

fn main ()
{
    let pathbuf = std::path::PathBuf::from(r"/hello/world/Alarm__123.timer");
    dbg!(parse_id(&pathbuf));
}

Also note that you do not need the .to_string() conversion, which would save a string duplication.