---
title: Indicating error, returning Result of Ok or Err in Rust
timestamp: 2024-03-14T10:30:01
author: szabgab
published: true
description: They way a function can indicate success or failure is by returning a Result enum.
tags:
    - Result
    - Error
    - Err
    - Ok
    - return
    - match
    - format!
    - static
    - "&'static"
---

Some function we implement might fail. Either because the caller did not supply the correct parameter or some other issue. How can we indicate failure?
In some languages failure is indicated by the raising (throwing) of exceptions. In other languages the function can return some value (e.g. null, undef etc.)
to indicate failure.

In Rust a function that might need to report an error should return a value of [Result](https://doc.rust-lang.org/std/result/) type. In general a Result
can have either a value wrapped in `Ok()` or a value wrapped in `Err()`. What kind of values are wrapped in either of those is up to the author of the function.

In the first example we have a function that expects an integer number between -100 and +100 and then checks if the number is smaller or bigger or exactly the same
as the `hidden_number`. This might be part of a number guessing game where the hidden number was generated by a random generator. However now we would like to focus
on the error reporting part.

The `guess` function return `Result<&'static str, &'static str>`. The generic description of Result is `Result<T, E>` so the first type is the type of the successful result
the second type is that of the error. In our case they are both `static` strings that are baked in the binary at compilation time.

In case the user supplied a number that is out of range we return a static string wrapped in the `Err()` call.

In case the number was in range we supply our message wrapped in an `Ok()` call.

The caller will receive a value of `Result` type and it has to be handled somehow. There are plenty of ways to handle it. For example calling `unwrap` will `panic!` if the result contained something
wrapped in `Err` and will return the content of the `Ok()` if the result contained a value wrapped in `Ok()`. This is mostly used in tests.

The caller can also use `match` to handle both the `Ok()` and the `Err()` case with additional code.

See the [functions associated with Result enum](https://doc.rust-lang.org/std/result/enum.Result.html) to find more ways to handle the errors.

{% include file="examples/return-result-str/src/main.rs" %}


## Returning a String generated on the fly

We might want to be more precise in our error message and even include the number we received. In this case we need to generate the error message
while the program is already running so we cannot return a `static` string wrapped in `Err()`. Therefore we change the second type in the returning `Result`
to be `String`.

This has some impact on how we generate the error message using the `format!` macro and how we use `String::from` when we would like to verify the results.

{% include file="examples/return-result-string/src/main.rs" %}


## Notes

There are many more types we can return as part of a `Result` enum.

There are plenty more ways to handle the `Result` by the caller.

It just occurred to me that including the valid range in the error message would be even more useful. I'll leave it as an exercise to the reader.


