Skip to content

Commit e43bc28

Browse files
authored
Call handler.poll_ready() before handler.call() (#437)
According to the tower::Service documentation and API contract, `poll_ready` must be called and a `Poll:Ready` must be obtained before invoking `call`
1 parent 75e18dd commit e43bc28

File tree

1 file changed

+44
-29
lines changed

1 file changed

+44
-29
lines changed

lambda-runtime/src/lib.rs

+44-29
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use serde::{Deserialize, Serialize};
1313
use std::{convert::TryFrom, env, fmt, future::Future, panic};
1414
use tokio::io::{AsyncRead, AsyncWrite};
1515
use tokio_stream::{Stream, StreamExt};
16-
use tower::util::ServiceFn;
1716
pub use tower::{self, service_fn, Service};
17+
use tower::{util::ServiceFn, ServiceExt};
1818
use tracing::{error, trace};
1919

2020
mod requests;
@@ -112,41 +112,56 @@ where
112112
env::set_var("_X_AMZN_TRACE_ID", xray_trace_id);
113113

114114
let request_id = &ctx.request_id.clone();
115-
let task = panic::catch_unwind(panic::AssertUnwindSafe(|| handler.call(LambdaEvent::new(body, ctx))));
116-
117-
let req = match task {
118-
Ok(response) => match response.await {
119-
Ok(response) => {
120-
trace!("Ok response from handler (run loop)");
121-
EventCompletionRequest {
122-
request_id,
123-
body: response,
124-
}
125-
.into_req()
126-
}
127-
Err(err) => {
128-
error!("{:?}", err); // logs the error in CloudWatch
129-
EventErrorRequest {
130-
request_id,
131-
diagnostic: Diagnostic {
132-
error_type: type_name_of_val(&err).to_owned(),
133-
error_message: format!("{}", err), // returns the error to the caller via Lambda API
134-
},
115+
let req = match handler.ready().await {
116+
Ok(handler) => {
117+
let task =
118+
panic::catch_unwind(panic::AssertUnwindSafe(|| handler.call(LambdaEvent::new(body, ctx))));
119+
match task {
120+
Ok(response) => match response.await {
121+
Ok(response) => {
122+
trace!("Ok response from handler (run loop)");
123+
EventCompletionRequest {
124+
request_id,
125+
body: response,
126+
}
127+
.into_req()
128+
}
129+
Err(err) => {
130+
error!("{:?}", err); // logs the error in CloudWatch
131+
EventErrorRequest {
132+
request_id,
133+
diagnostic: Diagnostic {
134+
error_type: type_name_of_val(&err).to_owned(),
135+
error_message: format!("{}", err), // returns the error to the caller via Lambda API
136+
},
137+
}
138+
.into_req()
139+
}
140+
},
141+
Err(err) => {
142+
error!("{:?}", err);
143+
EventErrorRequest {
144+
request_id,
145+
diagnostic: Diagnostic {
146+
error_type: type_name_of_val(&err).to_owned(),
147+
error_message: if let Some(msg) = err.downcast_ref::<&str>() {
148+
format!("Lambda panicked: {}", msg)
149+
} else {
150+
"Lambda panicked".to_string()
151+
},
152+
},
153+
}
154+
.into_req()
135155
}
136-
.into_req()
137156
}
138-
},
157+
}
139158
Err(err) => {
140-
error!("{:?}", err);
159+
error!("{:?}", err); // logs the error in CloudWatch
141160
EventErrorRequest {
142161
request_id,
143162
diagnostic: Diagnostic {
144163
error_type: type_name_of_val(&err).to_owned(),
145-
error_message: if let Some(msg) = err.downcast_ref::<&str>() {
146-
format!("Lambda panicked: {}", msg)
147-
} else {
148-
"Lambda panicked".to_string()
149-
},
164+
error_message: format!("{}", err), // returns the error to the caller via Lambda API
150165
},
151166
}
152167
.into_req()

0 commit comments

Comments
 (0)