---
title: Error Propagation
canonical_url: https://mew-lang.org/language/error-propagation/
sidecar_url: https://mew-lang.org/language/error-propagation.md
content_hash: sha256:f214f658184f53ca37025cdf137c6501a0ff047fc15b95b7fe663851abf607ab
tokens: 1109
uid: language.error-propagation
reading_time_minutes: 3
---

Language
# Error Propagation

 
`?` passes an error on to the caller. Put it after a call that returns a [Result](https://mew-lang.org/language/options-and-results.md). If the call succeeded, you get its value. If it failed, your function returns the error right there:

 
```mew
pub fn double(text: string) -> Result<i32, std.convert.ConvertError> {
    let n = text.parse_i32()?;
    return .ok(n * 2);
}
  
println($"{double("21").unwrap()}");
println(double("abc").err().unwrap().describe());
```

 
```
42
not a number
```

 
Without `?`, the same function needs a `match`:

 
```mew
pub fn double(text: string) -> Result<i32, std.convert.ConvertError> {
    match text.parse_i32() {
        .ok(n) => {
            return .ok(n * 2);
        },
        .err(reason) => {
            return .err(reason);
        },
    }
}
```

 
On an `Option`, `?` works the same way, with `none` in place of the error:

 
```mew
pub fn first_long_length(words: string[]) -> Option<i32> {
    let word = words.find(|w| w.length() > 3)?;
    return .some(word.length());
}
  
println($"{first_long_length(new string[] { "a", "mew", "kitten" })}");
println($"{first_long_length(new string[] { "a", "mew" })}");
```

 
```
some(6)
none
```

 
## Steps that return nothing

 
A function that can fail but has nothing to return gives back a `Result<(), E>`. `()` is the unit type, and its one value is also written `()`. Put `?` after the call on a line of its own, and the rest of your function only runs if the call succeeded:

 
```mew
pub fn check(name: string) -> Result<(), string> {
    if name.is_empty() {
        return .err("a name is needed");
    }
  
    return .ok(());
}
  
pub fn greet(name: string) -> Result<(), string> {
    check(name)?;
    println($"Hello, {name}!");
    return .ok(());
}
  
greet("ada").unwrap();
println(greet("").err().unwrap_or(""));
```

 
```
Hello, ada!
a name is needed
```

 
## Where `?` can go

 
`?` returns from the function it's in, so that function has to return the same kind of union: a `Result` for a `Result`, and an `Option` for an `Option`. Anywhere else, including the top level of `main.mew`, it's an error:

 
```mew
pub fn report(text: string) {
    let n = text.parse_i32()?;
    println($"{n}");
}
```

 
To use `?` on an `Option` in a function that returns a `Result`, turn it into a `Result` first with `ok_or`:

 
```mew
pub fn first_even(values: i32[]) -> Result<i32, string> {
    let found = values.find(|n| n % 2 == 0).ok_or("no even number")?;
    return .ok(found);
}
  
println($"{first_even(new i32[] { 3, 4 }).unwrap()}");
println(first_even(new i32[] { 3 }).err().unwrap_or(""));
```

 
```
4
no even number
```

 
## When the error types differ

 
If the error has your function's error type, or converts to it, `?` passes it on unchanged. An error converts to an [interface](https://mew-lang.org/language/interfaces.md) it implements, for example.

 
Otherwise, implement `Into` for the error, and `?` converts it on the way out:

 
```mew
pub type DiskError {
    pub field code: i32;
}
  
pub type AppError {
    pub field message: string;
}
  
impl Into<AppError> for DiskError {
    pub fn into() -> AppError {
        return new AppError { message: $"disk error {self.code}" };
    }
}
  
pub fn read(code: i32) -> Result<i32, DiskError> {
    if code > 0 {
        return .err(new DiskError { code: code });
    }
  
    return .ok(40);
}
  
pub fn load(code: i32) -> Result<i32, AppError> {
    return .ok(read(code)? + 2);
}
  
println($"{load(0).unwrap()}");
println(load(7).err().unwrap().message);
```

 
```
42
disk error 7
```

 
`?` binds as tightly as indexing. In `.ok(read(code)? + 2)`, it applies to `read(code)`, and the `+ 2` only runs when there is a value.

 
You can also convert the error yourself with `map_err` before the `?`:

 
```mew
pub fn read(text: string) -> Result<i32, string> {
    let n = text.parse_i32().map_err(|error| error.describe())?;
    return .ok(n * 2);
}
  
println(read("abc").err().unwrap_or(""));
```

 
```
not a number
```

 
If none of these apply, the code doesn't compile:

 
```mew
pub fn read(text: string) -> Result<i32, string> {
    let n = text.parse_i32()?;
    return .ok(n);
}
```

 
[Previous
                
                Options and Results](https://mew-lang.org/language/options-and-results.md)[Next
                    
                Names and Scopes](https://mew-lang.org/language/names.md)