-
Notifications
You must be signed in to change notification settings - Fork 361
[Do not merge] Refactor to address RFCs #63
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
Changes from 20 commits
a77abb1
36bcc8f
f53bd30
8b6d8fc
2e034d2
4f20464
d17b7c8
08772e9
a6d2c5b
fee02e8
4969624
0bce533
bd3cb34
5b9bad9
9ed9a43
7fa1167
5165242
3bcb150
ab54a2e
99b1328
3844b43
fa2a5b1
b6423f7
77459b5
ecbae1c
6896b1b
3f79fcb
1b1e624
7de9169
b991438
bedbf92
e3f6b34
253a481
db7f994
f0de223
d705def
a3aaedb
fd35180
8827cdb
32cd6e0
0f54490
bb61d71
6891eaa
ee12d37
315c979
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
/target | ||
/.cargo | ||
lambda-runtime/libtest.rmeta |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
[workspace] | ||
members = [ | ||
"lambda-runtime-client", | ||
"lambda-runtime-core", | ||
"lambda-runtime", | ||
"lambda-http" | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,31 @@ | ||
//! This module defines the `RuntimeApiError` trait that developers should implement | ||
//! to send their custom errors to the AWS Lambda Runtime Client SDK. The module also | ||
//! defines the `ApiError` type returned by the `RuntimeClient` implementations. | ||
use std::{env, error::Error, fmt, io, num::ParseIntError, option::Option}; | ||
|
||
use backtrace; | ||
use http::{header::ToStrError, uri::InvalidUri}; | ||
use hyper; | ||
use serde_derive::Serialize; | ||
use log::*; | ||
use serde_derive::*; | ||
use serde_json; | ||
use std::{ | ||
env, | ||
error::Error, | ||
fmt::{self, Display}, | ||
io, | ||
num::ParseIntError, | ||
option::Option, | ||
}; | ||
|
||
/// Error type description for the `ErrorResponse` event. This type should be returned | ||
/// for errors that were handled by the function code or framework. | ||
pub const ERROR_TYPE_HANDLED: &str = "Handled"; | ||
#[allow(dead_code)] | ||
pub(crate) const ERROR_TYPE_HANDLED: &str = "Handled"; | ||
sapessi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// Error type description for the `ErrorResponse` event. This type is used for unhandled, | ||
/// unexpcted errors. | ||
pub const ERROR_TYPE_UNHANDLED: &str = "Unhandled"; | ||
pub(crate) const ERROR_TYPE_UNHANDLED: &str = "Unhandled"; | ||
/// Error type for the error responses to the Runtime APIs. In the future, this library | ||
/// should use a customer-generated error code | ||
pub const RUNTIME_ERROR_TYPE: &str = "RustRuntimeError"; | ||
|
||
/// This object is used to generate requests to the Lambda Runtime APIs. | ||
/// It is used for both the error response APIs and fail init calls. | ||
|
@@ -37,6 +48,38 @@ pub struct ErrorResponse { | |
} | ||
|
||
impl ErrorResponse { | ||
/// Creates a new instance of the `ErrorResponse` object with the given parameters. If the | ||
/// `RUST_BACKTRACE` env variable is `1` the `ErrorResponse` is populated with the backtrace | ||
/// collected through the [`backtrace` craete](https://crates.io/crates/backtrace). | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `message` The error message to be returned to the APIs. Normally the error description() | ||
/// * `err_type` The error type. Use the `ERROR_TYPE_HANDLED` and `ERROR_TYPE_UNHANDLED`. | ||
/// * `code` A custom error code | ||
/// | ||
/// # Return | ||
/// A new instance of the `ErrorResponse` object. | ||
fn new(message: String, err_type: String) -> ErrorResponse { | ||
let mut err = ErrorResponse { | ||
error_message: message, | ||
error_type: err_type, | ||
stack_trace: Option::default(), | ||
}; | ||
let is_backtrace = env::var("RUST_BACKTRACE"); | ||
if is_backtrace.is_ok() && is_backtrace.unwrap() == "1" { | ||
trace!("Begin backtrace collection"); | ||
let trace = Option::from(backtrace::Backtrace::new()); | ||
let trace_string = format!("{:?}", trace) | ||
.lines() | ||
.map(|s| s.to_string()) | ||
.collect::<Vec<String>>(); | ||
trace!("Completed backtrace collection"); | ||
err.stack_trace = Option::from(trace_string); | ||
sapessi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
err | ||
} | ||
|
||
/// Creates a new `RuntimeError` object with the handled error type. | ||
/// | ||
/// # Arguments | ||
|
@@ -46,11 +89,7 @@ impl ErrorResponse { | |
/// # Return | ||
/// A populated `RuntimeError` object that can be used with the Lambda Runtime API. | ||
pub fn handled(message: String) -> ErrorResponse { | ||
ErrorResponse { | ||
error_message: message, | ||
error_type: String::from(ERROR_TYPE_HANDLED), | ||
stack_trace: Option::default(), | ||
} | ||
ErrorResponse::new(message, RUNTIME_ERROR_TYPE.to_owned()) | ||
} | ||
|
||
/// Creates a new `RuntimeError` object with the unhandled error type. | ||
|
@@ -62,33 +101,20 @@ impl ErrorResponse { | |
/// # Return | ||
/// A populated `RuntimeError` object that can be used with the Lambda Runtime API. | ||
pub fn unhandled(message: String) -> ErrorResponse { | ||
ErrorResponse { | ||
error_message: message, | ||
error_type: String::from(ERROR_TYPE_UNHANDLED), | ||
stack_trace: Option::default(), | ||
} | ||
ErrorResponse::new(message, RUNTIME_ERROR_TYPE.to_owned()) | ||
} | ||
} | ||
|
||
/// Custom errors for the framework should implement this trait. The client calls | ||
/// the `to_response()` method automatically to produce an object that can be serialized | ||
/// and sent to the Lambda Runtime APIs. | ||
pub trait RuntimeApiError { | ||
/// Creates a `RuntimeError` object for the current error. This is | ||
/// then serialized and sent to the Lambda runtime APIs. | ||
/// | ||
/// # Returns | ||
/// A populated `RuntimeError` object. | ||
fn to_response(&self) -> ErrorResponse; | ||
impl<T: Display + Send + Sync> From<Box<T>> for ErrorResponse { | ||
fn from(e: Box<T>) -> Self { | ||
Self::handled(format!("{}", e)) | ||
} | ||
} | ||
|
||
/// Represents an error generated by the Lambda Runtime API client. | ||
#[derive(Debug, Clone)] | ||
pub struct ApiError { | ||
msg: String, | ||
/// The `Backtrace` object from the `backtrace` crate used to store | ||
/// the stack trace of the error. | ||
pub backtrace: Option<backtrace::Backtrace>, | ||
/// Whether the current error is recoverable. If the error is not | ||
/// recoverable a runtime should panic to force the Lambda service | ||
/// to restart the execution environment. | ||
|
@@ -97,16 +123,8 @@ pub struct ApiError { | |
|
||
impl ApiError { | ||
pub(crate) fn new(description: &str) -> ApiError { | ||
let mut trace: Option<backtrace::Backtrace> = None; | ||
let is_backtrace = env::var("RUST_BACKTRACE"); | ||
if is_backtrace.is_ok() && is_backtrace.unwrap() == "1" { | ||
trace!("Begin backtrace collection"); | ||
trace = Option::from(backtrace::Backtrace::new()); | ||
trace!("Completed backtrace collection"); | ||
} | ||
ApiError { | ||
msg: String::from(description), | ||
backtrace: trace, | ||
recoverable: true, | ||
} | ||
} | ||
|
@@ -135,6 +153,8 @@ impl Error for ApiError { | |
None | ||
} | ||
} | ||
unsafe impl Send for ApiError {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, why's this is necessary? would be useful to add a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will go away, with the next iteration all errors will switch to failure. I have quite a bit of legacy error handling code in here. Just wanted to make one big change at a time. |
||
unsafe impl Sync for ApiError {} | ||
|
||
impl From<serde_json::Error> for ApiError { | ||
fn from(e: serde_json::Error) -> Self { | ||
|
@@ -171,14 +191,3 @@ impl From<io::Error> for ApiError { | |
ApiError::new(e.description()) | ||
} | ||
} | ||
|
||
impl RuntimeApiError for ApiError { | ||
fn to_response(&self) -> ErrorResponse { | ||
let backtrace = format!("{:?}", self.backtrace); | ||
let trace_vec = backtrace.lines().map(|s| s.to_string()).collect::<Vec<String>>(); | ||
let mut err = ErrorResponse::unhandled(self.msg.clone()); | ||
err.stack_trace = Option::from(trace_vec); | ||
|
||
err | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "lambda_runtime_core" | ||
version = "0.1.0" | ||
authors = ["Stefano Buliani", "David Barsky"] | ||
description = "Rust runtime for AWS Lambda" | ||
keywords = ["AWS", "Lambda", "Runtime", "Rust"] | ||
license = "Apache-2.0" | ||
homepage = "https://github.com/awslabs/aws-lambda-rust-runtime" | ||
repository = "https://github.com/awslabs/aws-lambda-rust-runtime" | ||
documentation = "https://docs.rs/lambda_runtime" | ||
edition = "2018" | ||
|
||
[dependencies] | ||
log = "^0.4" | ||
hyper = "^0.12" | ||
tokio = "^0.1" | ||
backtrace = "^0.3" | ||
lambda_runtime_client = { path = "../lambda-runtime-client", version = "^0.1" } | ||
chrono = "^0.4" | ||
|
||
[dev-dependencies] | ||
failure = "^0.1" | ||
simple_logger = "^1" |
Uh oh!
There was an error while loading. Please reload this page.