Description
Currently, the Lambda Rust runtime declares a HandlerError
type that developers can use to return an error from their handler method. While this approach works, it forces developers to write more verbose code to handle all errors and generate the relevant HandlerError
objects. Developers would like to return errors automatically using the ?
operator (#23).
For example:
fn my_handler(e: CustomEvent, c: lambda::Context) -> Result<CustomOutput, Error> {
let i = event.age.parse::<u8>?;
...
}
In an error response, the Lambda runtime API expects two parameters: errorType
and errorMessage
. Optionally, we can also attach a stack trace to the error.
{
"errorMessage" : "Error parsing age data.",
"errorType" : "InvalidAgeException"
}
To generate an error message field we need the Err
variant from the handler Result
to support the Display
trait. This allows us to support any Display
type in the result - Error
types inherently supports Display
too. However, we cannot identify a way to automatically generate the error type field given a Display
-compatible object that uses stable features. To address this, we plan to introduce a new trait in the runtime:
pub trait ErrorExt {
fn error_type(&self) -> &str;
}
We'd like to deprecate this trait in the future and rely on the type name intrinsic (which is currently blocked on specialization). For context, see #1428.
The name ErrorExt comes from the extension trait conventions RFC. Based on feedback, we are open to changing this.
The runtime crate itself will provide the implementation of the ErrorExt
trait for the most common errors in the standard library. Developers will have to implement the trait themselves in their own errors. We may consider adding a procedural macro to the runtime crate to automatically generate the trait implementation.
In summary, the proposed changes are:
- The handler type will accept any object that implements
Display
andErrorExt
in itsErr
variant. - The runtime crate will use the
Display
trait to extract an error message and use theISO-8859-1
charset. - The runtime crate will call the
error_type()
function to get the value for theerrorType
field. - If the
RUST_BACKTRACE
environment variable is set to1
, the runtime will use the backtrace crate to collect a stack trace as soon as the error is received.
The new handler type definition will be:
pub trait Handler<Event, Output, Error>
where
Event: From<Vec<u8>>,
Output: Into<Vec<u8>>,
Error: Display + ErrorExt + Send + Sync,
{
fn run(&mut self, event: Event, ctx: Context) -> Result<Output, Error>;
}