| 69 | type Output = Result<(), BoxError>; |
| 70 | |
| 71 | fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> { |
| 72 | // NOTE: We loop here to directly poll the second future once the first has finished. |
| 73 | task::Poll::Ready(loop { |
| 74 | match self.as_mut().project() { |
| 75 | RuntimeApiClientFutureProj::First(fut, client) => match ready!(fut.poll(cx)) { |
| 76 | Ok(ok) => { |
| 77 | // NOTE: We use 'client.call_boxed' here to obtain a future with static |
| 78 | // lifetime. Otherwise, this future would need to be self-referential... |
| 79 | let next_fut = client |
| 80 | .call(ok) |
| 81 | .map_err(|err| { |
| 82 | error!(error = ?err, "failed to send request to Lambda Runtime API"); |
| 83 | err |
| 84 | }) |
| 85 | .boxed(); |
| 86 | self.set(RuntimeApiClientFuture::Second(next_fut)); |
| 87 | } |
| 88 | Err(err) => { |
| 89 | log_or_print!( |
| 90 | tracing: tracing::error!(error = ?err, "failed to build Lambda Runtime API request"), |
| 91 | fallback: eprintln!("failed to build Lambda Runtime API request: {err:?}") |
| 92 | ); |
| 93 | break Err(err); |
| 94 | } |
| 95 | }, |
| 96 | RuntimeApiClientFutureProj::Second(fut) => match ready!(fut.poll(cx)) { |
| 97 | Ok(resp) if !resp.status().is_success() => { |
| 98 | let status = resp.status(); |
| 99 | |
| 100 | // TODO |
| 101 | // we should consume the response body of the call in order to give a more specific message. |
| 102 | // https://github.com/aws/aws-lambda-rust-runtime/issues/1110 |
| 103 | |
| 104 | log_or_print!( |
| 105 | tracing: tracing::error!(status = %status, "Lambda Runtime API returned non-200 response"), |
| 106 | fallback: eprintln!("Lambda Runtime API returned non-200 response: status={status}") |
| 107 | ); |
| 108 | |
| 109 | // Adding more information on top of 410 Gone, to make it more clear since we cannot access the body of the message |
| 110 | if status == 410 { |
| 111 | log_or_print!( |
| 112 | tracing: tracing::error!("Lambda function timeout!"), |
| 113 | fallback: eprintln!("Lambda function timeout!") |
| 114 | ); |
| 115 | } |
| 116 | |
| 117 | // Return Ok to maintain existing contract - runtime continues despite API errors |
| 118 | break Ok(()); |
| 119 | } |
| 120 | Ok(_) => break Ok(()), |
| 121 | Err(err) => { |
| 122 | log_or_print!( |
| 123 | tracing: tracing::error!(error = ?err, "Lambda Runtime API request failed"), |
| 124 | fallback: eprintln!("Lambda Runtime API request failed: {err:?}") |
| 125 | ); |
| 126 | break Err(err); |
| 127 | } |
| 128 | }, |