Skip to content

Commit fa3347f

Browse files
committed
Simplify implementation, remove IntoDiagnostic
We can implement `From<T> for Diagnostic` for error crates.
1 parent 0e10bdd commit fa3347f

File tree

4 files changed

+58
-143
lines changed

4 files changed

+58
-143
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,13 @@ We recommend you to use the [thiserror crate](https://crates.io/crates/thiserror
114114

115115
Popular error crates like Anyhow, Eyre, and Miette provide their own error types that encapsulate other errors. There is no direct transformation of those errors into `Diagnostic`, but we provide feature flags for each one of those crates to help you integrate them with your Lambda functions.
116116

117-
If you enable the features `anyhow`, `eyre`, or `miette` in the `lambda_runtime` dependency of your package. The error types provided by those crates can have blanket transformations into `Diagnostic` when the `lambda_runtime::IntoDiagnostic` trait is in scope. This trait exposes an `into_diagnostic` method that transforms those error types into a `Diagnostic`. This is an example that transforms an `anyhow::Error` into a `Diagnostic`:
117+
If you enable the features `anyhow`, `eyre`, or `miette` in the `lambda_runtime` dependency of your package. The error types provided by those crates can have blanket transformations into `Diagnostic`. These features expose an `From<T> for Diagnostic` implementation that transforms those error types into a `Diagnostic`. This is an example that transforms an `anyhow::Error` into a `Diagnostic`:
118118

119119
```rust
120-
use lambda_runtime::{Diagnostic, IntoDiagnostic, LambdaEvent};
120+
use lambda_runtime::{Diagnostic, LambdaEvent};
121121

122122
async fn handler(_event: LambdaEvent<Request>) -> Result<(), Diagnostic> {
123-
Err(anyhow::anyhow!("this is an error").into_diagnostic())
123+
Err(anyhow::anyhow!("this is an error").into())
124124
}
125125
```
126126

examples/basic-error-error-crates-integration/src/main.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use lambda_runtime::{run, service_fn, Diagnostic, IntoDiagnostic, Error, LambdaEvent};
1+
use lambda_runtime::{run, service_fn, Diagnostic, Error, LambdaEvent};
22
use serde::Deserialize;
33

44
#[derive(Deserialize)]
@@ -27,14 +27,14 @@ fn miette_error() -> miette::Result<()> {
2727
}
2828

2929
/// Transform an anyhow::Error, eyre::Report, or miette::Report into a lambda_runtime::Diagnostic.
30-
/// It does it by enabling the feature `anyhow`, `eyre` or `miette` in the runtime dependency,
31-
/// and importing the `IntoDiagnostic` trait, which enables
32-
/// the implementation of `into_diagnostic` for `anyhow::Error`, `eyre::Report`, and `miette::Report`.
30+
/// It does it by enabling the feature `anyhow`, `eyre` or `miette` in the runtime dependency.
31+
/// Those features enable the implementation of `From<T> for Diagnostic`
32+
/// for `anyhow::Error`, `eyre::Report`, and `miette::Report`.
3333
async fn function_handler(event: LambdaEvent<Request>) -> Result<(), Diagnostic> {
3434
match event.payload.error_type {
35-
ErrorType::Anyhow => anyhow_error().map_err(|e| e.into_diagnostic()),
36-
ErrorType::Eyre => eyre_error().map_err(|e| e.into_diagnostic()),
37-
ErrorType::Miette => miette_error().map_err(|e| e.into_diagnostic()),
35+
ErrorType::Anyhow => anyhow_error().map_err(|e| e.into()),
36+
ErrorType::Eyre => eyre_error().map_err(|e| e.into()),
37+
ErrorType::Miette => miette_error().map_err(|e| e.into()),
3838
}
3939
}
4040

lambda-runtime/src/diagnostic.rs

Lines changed: 47 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -55,124 +55,21 @@ pub struct Diagnostic {
5555
pub error_message: String,
5656
}
5757

58-
/// Trait that adds an `into_diagnostic` method to several types,
59-
/// including standard errors, and error types from several well known error crates.
60-
///
61-
/// This trait is automatically implemented for some common types,
62-
/// like boxed types that implement [`Error`][std::error::Error].
63-
/// If you use an error type which comes from a external crate like anyhow, eyre, or miette,
64-
/// you can enable the features `anyhow`, `eyre` or `miette` in the `lambda_runtime` crate to automatically
65-
/// implement `IntoDiagnostic`.
66-
///
67-
/// Example:
68-
/// ```
69-
/// use lambda_runtime::{Diagnostic, IntoDiagnostic, LambdaEvent};
70-
///
71-
/// #[derive(Debug)]
72-
/// struct ErrorResponse(&'static str);
73-
///
74-
/// impl IntoDiagnostic for ErrorResponse {
75-
/// fn into_diagnostic(self) -> Diagnostic {
76-
/// Diagnostic {
77-
/// error_type: "MyError".into(),
78-
/// error_message: self.0.into(),
79-
/// }
80-
/// }
81-
/// }
82-
///
83-
/// async fn function_handler(_event: LambdaEvent<()>) -> Result<(), Diagnostic> {
84-
/// Err(ErrorResponse("this is an error response").into_diagnostic())
85-
/// }
86-
/// ```
87-
pub trait IntoDiagnostic {
88-
/// Converts external error types into [`Diagnostic`]
89-
fn into_diagnostic(self) -> Diagnostic;
90-
}
91-
92-
impl IntoDiagnostic for DeserializeError {
93-
fn into_diagnostic(self) -> Diagnostic {
94-
Diagnostic {
95-
error_type: type_name_of_val(&self),
96-
error_message: self.to_string(),
97-
}
98-
}
99-
}
100-
101-
impl IntoDiagnostic for Error {
102-
fn into_diagnostic(self) -> Diagnostic {
103-
Diagnostic {
104-
error_type: type_name_of_val(&self),
105-
error_message: self.to_string(),
106-
}
107-
}
108-
}
109-
110-
impl IntoDiagnostic for Box<dyn std::error::Error> {
111-
fn into_diagnostic(self) -> Diagnostic {
112-
Diagnostic {
113-
error_type: type_name_of_val(&self),
114-
error_message: self.to_string(),
115-
}
116-
}
117-
}
118-
119-
impl IntoDiagnostic for std::convert::Infallible {
120-
fn into_diagnostic(self) -> Diagnostic {
121-
Diagnostic {
122-
error_type: type_name_of_val(&self),
123-
error_message: self.to_string(),
124-
}
125-
}
126-
}
127-
128-
impl IntoDiagnostic for String {
129-
fn into_diagnostic(self) -> Diagnostic {
130-
Diagnostic {
131-
error_type: type_name_of_val(&self),
132-
error_message: self,
133-
}
134-
}
135-
}
136-
137-
impl IntoDiagnostic for &'static str {
138-
fn into_diagnostic(self) -> Diagnostic {
139-
Diagnostic {
140-
error_type: type_name_of_val(&self),
141-
error_message: self.into(),
142-
}
143-
}
144-
}
145-
146-
impl IntoDiagnostic for std::io::Error {
147-
fn into_diagnostic(self) -> Diagnostic {
148-
Diagnostic {
149-
error_type: type_name_of_val(&self),
150-
error_message: self.to_string(),
151-
}
152-
}
153-
}
154-
155-
impl<T> IntoDiagnostic for Box<T>
156-
where
157-
T: std::error::Error,
158-
{
159-
fn into_diagnostic(self) -> Diagnostic {
160-
Diagnostic {
161-
error_type: type_name_of_val(&self),
162-
error_message: self.to_string(),
163-
}
164-
}
165-
}
166-
16758
impl From<DeserializeError> for Diagnostic {
16859
fn from(value: DeserializeError) -> Self {
169-
value.into_diagnostic()
60+
Diagnostic {
61+
error_type: type_name_of_val(&value),
62+
error_message: value.to_string(),
63+
}
17064
}
17165
}
17266

17367
impl From<Error> for Diagnostic {
17468
fn from(value: Error) -> Self {
175-
value.into_diagnostic()
69+
Diagnostic {
70+
error_type: type_name_of_val(&value),
71+
error_message: value.to_string(),
72+
}
17673
}
17774
}
17875

@@ -181,66 +78,84 @@ where
18178
T: std::error::Error,
18279
{
18380
fn from(value: Box<T>) -> Self {
184-
value.into_diagnostic()
81+
Diagnostic {
82+
error_type: type_name_of_val(&value),
83+
error_message: value.to_string(),
84+
}
18585
}
18686
}
18787

18888
impl From<Box<dyn std::error::Error>> for Diagnostic {
18989
fn from(value: Box<dyn std::error::Error>) -> Self {
190-
value.into_diagnostic()
90+
Diagnostic {
91+
error_type: type_name_of_val(&value),
92+
error_message: value.to_string(),
93+
}
19194
}
19295
}
19396

19497
impl From<std::convert::Infallible> for Diagnostic {
19598
fn from(value: std::convert::Infallible) -> Self {
196-
value.into_diagnostic()
99+
Diagnostic {
100+
error_type: type_name_of_val(&value),
101+
error_message: value.to_string(),
102+
}
197103
}
198104
}
199105

200106
impl From<String> for Diagnostic {
201107
fn from(value: String) -> Self {
202-
value.into_diagnostic()
108+
Diagnostic {
109+
error_type: type_name_of_val(&value),
110+
error_message: value.to_string(),
111+
}
203112
}
204113
}
205114

206115
impl From<&'static str> for Diagnostic {
207116
fn from(value: &'static str) -> Self {
208-
value.into_diagnostic()
117+
Diagnostic {
118+
error_type: type_name_of_val(&value),
119+
error_message: value.to_string(),
120+
}
209121
}
210122
}
211123

212124
impl From<std::io::Error> for Diagnostic {
213125
fn from(value: std::io::Error) -> Self {
214-
value.into_diagnostic()
126+
Diagnostic {
127+
error_type: type_name_of_val(&value),
128+
error_message: value.to_string(),
129+
}
215130
}
216131
}
217132

218133
#[cfg(feature = "anyhow")]
219-
impl IntoDiagnostic for anyhow::Error {
220-
fn into_diagnostic(self) -> Diagnostic {
134+
impl From<anyhow::Error> for Diagnostic {
135+
fn from(value: anyhow::Error) -> Diagnostic {
221136
Diagnostic {
222-
error_type: type_name_of_val(&self),
223-
error_message: self.to_string(),
137+
error_type: type_name_of_val(&value),
138+
error_message: value.to_string(),
224139
}
225140
}
226141
}
227142

228143
#[cfg(feature = "eyre")]
229-
impl IntoDiagnostic for eyre::Report {
230-
fn into_diagnostic(self) -> Diagnostic {
144+
impl From<eyre::Report> for Diagnostic {
145+
fn from(value: eyre::Report) -> Diagnostic {
231146
Diagnostic {
232-
error_type: type_name_of_val(&self),
233-
error_message: self.to_string(),
147+
error_type: type_name_of_val(&value),
148+
error_message: value.to_string(),
234149
}
235150
}
236151
}
237152

238153
#[cfg(feature = "miette")]
239-
impl IntoDiagnostic for miette::Report {
240-
fn into_diagnostic(self) -> Diagnostic {
154+
impl From<miette::Report> for Diagnostic {
155+
fn from(value: miette::Report) -> Diagnostic {
241156
Diagnostic {
242-
error_type: type_name_of_val(&self),
243-
error_message: self.to_string(),
157+
error_type: type_name_of_val(&value),
158+
error_message: value.to_string(),
244159
}
245160
}
246161
}
@@ -274,7 +189,7 @@ mod test {
274189
fn test_anyhow_integration() {
275190
use anyhow::Error as AnyhowError;
276191
let error: AnyhowError = anyhow::anyhow!("anyhow error");
277-
let diagnostic: Diagnostic = error.into_diagnostic();
192+
let diagnostic: Diagnostic = error.into();
278193
assert_eq!(diagnostic.error_type, "&anyhow::Error");
279194
assert_eq!(diagnostic.error_message, "anyhow error");
280195
}
@@ -284,7 +199,7 @@ mod test {
284199
fn test_eyre_integration() {
285200
use eyre::Report;
286201
let error: Report = eyre::eyre!("eyre error");
287-
let diagnostic: Diagnostic = error.into_diagnostic();
202+
let diagnostic: Diagnostic = error.into();
288203
assert_eq!(diagnostic.error_type, "&eyre::Report");
289204
assert_eq!(diagnostic.error_message, "eyre error");
290205
}
@@ -294,7 +209,7 @@ mod test {
294209
fn test_miette_integration() {
295210
use miette::Report;
296211
let error: Report = miette::miette!("miette error");
297-
let diagnostic: Diagnostic = error.into_diagnostic();
212+
let diagnostic: Diagnostic = error.into();
298213
assert_eq!(diagnostic.error_type, "&miette::eyreish::Report");
299214
assert_eq!(diagnostic.error_message, "miette error");
300215
}

lambda-runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use tower::{self, service_fn, Service};
2020

2121
/// Diagnostic utilities to convert Rust types into Lambda Error types.
2222
pub mod diagnostic;
23-
pub use diagnostic::{Diagnostic, IntoDiagnostic};
23+
pub use diagnostic::Diagnostic;
2424

2525
mod deserializer;
2626
/// Tower middleware to be applied to runtime invocations.

0 commit comments

Comments
 (0)