aws-lambda-rust-runtime: awkward HandlerError requirements
I’m finding that, in practice, the new HandlerError’ type constraints may have made error handling hard/awkward to satisfy for users
common cases I run into is trying to represent a foreign crate type for with lambda_runtime_errors::LambdaErrorExt. Since the Fail crate is becoming more common I think that’s okay, but still rough if the foreign crates error type sticks to the standard library error type
I find myself often cluttering map_err(HandlerError::new) code with this
// I don't control the Err type of foo_bar as its defined in another crate
// so I can't impl lambda_runtime_errors::LambdaErrorExt for ThatError { ... }
foo_bar(input).map_err(HandlerError::new)? // fails to compile because no impl for lambda_runtime_errors::LambdaErrorExt
This is unfortunate for users because often these are simple hello world integrate xxx with lambda cases where the majority of the code written is satisfying the trait constraints on errors and not the code what brings business value.
I understand why this constraint exists but I want to revisit the value for users this is providing vs what its costing to author lambdas.
I’ve ran into this enough that I wanted to reopen the floor for alternative options.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 9
- Comments: 25 (17 by maintainers)
Just looking at this from a high level, my recommendation would be to stick with
std::error::Error. The failure crate is far from standard.I would set bounds to:
E: Into<Box<std::error::Error + Send + Sync>>. Then provide:From the lambda runtime, to get the error name would be a two step process:
HandlerError. If you find one, use that as the name.HandlerErrorwas found, use theDebugimplementation and, assume the format isTypeName { [fields] }, parse out the name.Is it great? No… but my gut reaction is that it would work better than forcing the error to be
HandlerErroras no web framework or whatever would have that type, so getting access to the name of the root error would be tricky.Then, once
type_nameis stable, use that.Update on this. As mentioned above, there has been a lot of changes on master that diverge from what’s currently up on crates.io. These reflect some learnings, some simplification of the previous design, ergonomic improvements, and first class support for async/awaitable handlers.
The error ergonomics issues have mostly been resolved. The http module has been brought up to speed in this pull
https://github.com/awslabs/aws-lambda-rust-runtime/pull/217
Mostly anything impl std error will now do for errors.
Here’s an example
https://github.com/softprops/aws-lambda-rust-runtime/blob/a3852265f595dec6e8e993ce12b1080f2a38e0af/lambda-http/examples/basic.rs#L3
closing. I’m really happy with the state of the master branch
Looking forward to the new Error improvements. @rib thanks for the snippet, I was fighting that pretty hard as well. 😃
That’s a good point. I think the design I proposed is an acceptable long-term solution, but in the interest of addressing pain points now I think your proposal of a
HandlerError::named(err, "MyErrorName")is a good first step.That’s correct—for folks that don’t care about dashboarding error types, we’d rely on
HandlerError::default()(or just aString, as that allows us to place theHandlerErrorbehind a feature flag + cut down on compile times. Like you said, “At a minimum, that’s just an error message and type.”).That’s a good point. I’ll open a new issue with the handler design + close out https://github.com/awslabs/aws-lambda-rust-runtime/pull/62, as it’s pretty different now.
Something did catch my eye above though which is very near and dear to my heart. There was mention of cutting down compile times… 😃 I’m very interested in that topic.
Glad you noticed that 😀. I’ve noticed that because of Tower’s insistence on a bunch of tiny crates that, in composition, provide similar feature sets to Hyper, Cargo is able to compile these tiny crates in parallel.