-
Notifications
You must be signed in to change notification settings - Fork 359
Rust ergonomics for error handling #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for the feedback—we really appreciate it! I'm thinking of replacing the current setup with something that leverages (maybe) Failure and (for sure) ErrorKinds, and using something similar to what Sean proposed in tower-rs/tower#131. Would a system like this—behind a breaking change semver bump—be something like you're looking for? |
I think so. In my head, probably poorly thought out, the handler type would be An example of how I'm doing this, loosely based on fn map_handler_err(msg: &str, ctx: &Context, err: impl Error) -> HandlerError {
error!("{} in request {}",msg, ctx.aws_request_id);
ctx.new_error(&err.to_string())
}
fn my_handler(event: MsgEvent, ctx: Context) -> Result<MsgResponse, HandlerError> {
match record::Record::parse_base64(&event.msg) {
Ok(rec) => {
let s = rec.summary();
Ok(MsgResponse{id: s.id, sum: s.sum, longest: s.longest})
},
Err(e) => Err(map_handler_err("Message parsing error", &ctx, e))
}
} Which suggests a non-breaking old-style Rust error handling hack: a trait with a let r = record::Record::parse_base64(&event.msg).map_err_ctx(my_err_handler)?;
let s = r.summary();
Ok(MsgResponse{...} |
I like the idea. One more change we should couple with this: give you the ability to return a custom error code for the APIs. The Runtime APIs error structure is very simple, we could probably drop the |
Spoke to @sapessi about this. Long story short, we're considering several options:
Alternatively, we can define a handler in terms of std::future::Future (when stable, 6-12 weeks from now) which doesn't have an error field, just an associated type called |
The Runtime APIs expect a few properties with an error (listed below). Because these properties are relatively generic, nothing ties us to an
The The message should represent a description of the error. This is the one parameter I must get from the handler code. For this reason, David an I thought that The stack trace I can collect myself using the backtrace crate. We already do that if the RUST_BACKTRACE env variable is set. |
What does error "code" mean in this context? I would expect it to be an integer. What is it used for? |
Working on this myself @Sh4rK. From the documentation, I can see that there's an ...
/runtime/invocation/{AwsRequestId}/error:
post:
summary: >
Runtime makes this request in order to submit an error response. It can
be either a function error, or a runtime error. Error will be served in
response to the invoke.
parameters:
- in: path
name: AwsRequestId
schema:
type: string
required: true
- in: header
name: Lambda-Runtime-Function-Error-Type
schema:
type: string
... |
Got the clarification I needed and updated the original post |
I'm a bit confused.
|
Agree that it needs disambiguation. The only field that matters as far as handlers are concerned is the errorType in the body. We should find a way to populate that with a code that makes sense when looking at logs.
The field is not used at the moment. We should set it to Unhandled by default.
Agree. We may be able to solve this as we address the first point (generating the back trace much closer to the error or by standardizing to the failure crate. The first question we need to answer probably is: for the error result in the handler, do we want to rely on anything that implements Display, an Error from std, or a failure? Or perhaps something else I haven't considered at all. Once we have this answer, we can start planning the rest. |
What I wanted to find out is, where does this "We should set it to Unhandled" come from, that is, that Unhandled and Handled are the possible values for the header.
Actually, I think it should be possible to do all of them via some trait trickery, but I haven't tried. That way, if we get something (Small side note: |
That's what I've been told by the Lambda team - I have no more background than that.
That's what I've been trying to do (with very little success), as I understand we'd need specialization to make this work. The errors pull request is not the final implementation, more of a public playground to experiment with different ideas. We are talking through this internally now. Once we have some well formed thoughts, we'll update this issue with a full proposal.
|
@Sh4rK @arienmalec @srijs Hello! If you've got the time, @sapessi wrote up an RFC for error-handling. We'd appreciate feedback! |
Resolving since |
The examples for using the Rust Lambda runtime require additional calls around error handling that require access to the
Context
object.Unfortunately, that breaks Rust ergonomics for error handing, that ordinarily would use
?
and map custom errors toHandlerError
through animpl From
(which doesn't have a reference to theContext
struct.Ideally, I could return my own error types, and either have the runtime take care of supplying context, with perhaps some place to inject logging, etc. into the error handing flow.
In practice, in the short term, I'm breaking out all actions that can return a
Result
into a separate module, because even trivial activities get complicated quickly if you want to inject error handing with access toContext
.The text was updated successfully, but these errors were encountered: