diff --git a/BUILD b/BUILD index 7f611e4f..483e5ad4 100644 --- a/BUILD +++ b/BUILD @@ -39,6 +39,20 @@ rust_library( ], ) +rust_library( + name = "proxy_wasm_no_panic", + srcs = glob(["src/*.rs"]), + crate_features = ["no-panic"], + crate_name = "proxy_wasm", + edition = "2018", + visibility = ["//visibility:public"], + deps = [ + ":proxy_wasm_build_script", + "//bazel/cargo/remote:hashbrown", + "//bazel/cargo/remote:log", + ], +) + rust_binary( name = "http_auth_random", srcs = ["examples/http_auth_random/src/lib.rs"], diff --git a/Cargo.toml b/Cargo.toml index d51e2d86..8b1eb0ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,10 @@ build = "build.rs" hashbrown = "0.15" log = "0.4" +[features] +default = [] +no-panic = [] + [profile.release] lto = true opt-level = 3 diff --git a/examples/http_auth_random/Cargo.toml b/examples/http_auth_random/Cargo.toml index 69be9845..0bd54abe 100644 --- a/examples/http_auth_random/Cargo.toml +++ b/examples/http_auth_random/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib"] [dependencies] log = "0.4" -proxy-wasm = { path = "../../" } +proxy-wasm = { path = "../../", features = ["no-panic"] } [profile.release] lto = true diff --git a/src/dispatcher.rs b/src/dispatcher.rs index 19742565..5023f4cc 100644 --- a/src/dispatcher.rs +++ b/src/dispatcher.rs @@ -15,8 +15,8 @@ use crate::hostcalls; use crate::traits::*; use crate::types::*; +use crate::{dont_panic, maybe_panic}; use hashbrown::HashMap; -use log::trace; use std::cell::{Cell, RefCell}; thread_local! { @@ -100,7 +100,7 @@ impl Dispatcher { .insert(token_id, self.active_id.get()) .is_some() { - panic!("duplicate token_id") + maybe_panic!("register_callout: duplicate token_id") } } @@ -111,7 +111,7 @@ impl Dispatcher { .insert(token_id, self.active_id.get()) .is_some() { - panic!("duplicate token_id") + maybe_panic!("register_grpc_stream: duplicate token_id") } } @@ -122,7 +122,7 @@ impl Dispatcher { .insert(token_id, self.active_id.get()) .is_some() { - panic!("duplicate token_id") + maybe_panic!("register_grpc_callout: duplicate token_id") } } @@ -137,49 +137,62 @@ impl Dispatcher { .insert(context_id, new_context) .is_some() { - panic!("duplicate context_id") + maybe_panic!("create_root_context: duplicate context_id") } } fn create_stream_context(&self, context_id: u32, root_context_id: u32) { let new_context = match self.roots.borrow().get(&root_context_id) { Some(root_context) => match self.new_stream.get() { - Some(f) => f(context_id, root_context_id), - None => match root_context.create_stream_context(context_id) { - Some(stream_context) => stream_context, - None => panic!("create_stream_context returned None"), - }, + Some(f) => Some(f(context_id, root_context_id)), + None => root_context.create_stream_context(context_id), }, - None => panic!("invalid root_context_id"), + None => { + maybe_panic!("create_stream_context: invalid root_context_id"); + #[allow(unreachable_code)] + None + } }; - if self - .streams - .borrow_mut() - .insert(context_id, new_context) - .is_some() - { - panic!("duplicate context_id") + match new_context { + Some(new_context) => { + if self + .streams + .borrow_mut() + .insert(context_id, new_context) + .is_some() + { + maybe_panic!("create_stream_context: duplicate context_id") + } + } + None => maybe_panic!("create_stream_context: no context created"), } } fn create_http_context(&self, context_id: u32, root_context_id: u32) { let new_context = match self.roots.borrow().get(&root_context_id) { Some(root_context) => match self.new_http_stream.get() { - Some(f) => f(context_id, root_context_id), - None => match root_context.create_http_context(context_id) { - Some(stream_context) => stream_context, - None => panic!("create_http_context returned None"), - }, + Some(f) => Some(f(context_id, root_context_id)), + None => root_context.create_http_context(context_id), }, - None => panic!("invalid root_context_id"), + None => { + maybe_panic!("create_http_context:invalid root_context_id"); + #[allow(unreachable_code)] + None + } }; - if self - .http_streams - .borrow_mut() - .insert(context_id, new_context) - .is_some() - { - panic!("duplicate context_id") + + match new_context { + Some(new_context) => { + if self + .http_streams + .borrow_mut() + .insert(context_id, new_context) + .is_some() + { + maybe_panic!("create_http_context: duplicate context_id") + } + } + None => maybe_panic!("create_http_context: no context created"), } } @@ -198,10 +211,10 @@ impl Dispatcher { Some(ContextType::StreamContext) => { self.create_stream_context(context_id, root_context_id) } - None => panic!("missing ContextType on root_context"), + None => maybe_panic!("on_create_context: missing ContextType on root_context"), } } else { - panic!("invalid root_context_id and missing constructors"); + maybe_panic!("on_create_context: invalid root_context_id and missing constructors") } } @@ -216,7 +229,9 @@ impl Dispatcher { self.active_id.set(context_id); root.on_done() } else { - panic!("invalid context_id") + maybe_panic!("on_done: invalid context_id"); + #[allow(unreachable_code)] + true } } @@ -231,7 +246,7 @@ impl Dispatcher { self.active_id.set(context_id); root.on_log() } else { - panic!("invalid context_id") + maybe_panic!("on_log: invalid context_id") } } @@ -240,7 +255,7 @@ impl Dispatcher { || self.streams.borrow_mut().remove(&context_id).is_some() || self.roots.borrow_mut().remove(&context_id).is_some()) { - panic!("invalid context_id") + maybe_panic!("on_delete: invalid context_id") } } @@ -249,7 +264,9 @@ impl Dispatcher { self.active_id.set(context_id); root.on_vm_start(vm_configuration_size) } else { - panic!("invalid context_id") + maybe_panic!("on_vm_start: invalid context_id"); + #[allow(unreachable_code)] + true } } @@ -258,7 +275,9 @@ impl Dispatcher { self.active_id.set(context_id); root.on_configure(plugin_configuration_size) } else { - panic!("invalid context_id") + maybe_panic!("on_configure: invalid context_id"); + #[allow(unreachable_code)] + true } } @@ -267,7 +286,7 @@ impl Dispatcher { self.active_id.set(context_id); root.on_tick() } else { - panic!("invalid context_id") + maybe_panic!("on_tick: invalid context_id") } } @@ -276,7 +295,7 @@ impl Dispatcher { self.active_id.set(context_id); root.on_queue_ready(queue_id) } else { - panic!("invalid context_id") + maybe_panic!("on_queue_ready: invalid context_id") } } @@ -285,7 +304,9 @@ impl Dispatcher { self.active_id.set(context_id); stream.on_new_connection() } else { - panic!("invalid context_id") + maybe_panic!("on_new_connection: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -294,7 +315,9 @@ impl Dispatcher { self.active_id.set(context_id); stream.on_downstream_data(data_size, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_downstream_data: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -303,7 +326,7 @@ impl Dispatcher { self.active_id.set(context_id); stream.on_downstream_close(peer_type) } else { - panic!("invalid context_id") + maybe_panic!("on_downstream_close: invalid context_id") } } @@ -312,7 +335,9 @@ impl Dispatcher { self.active_id.set(context_id); stream.on_upstream_data(data_size, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_upstream_data: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -321,7 +346,7 @@ impl Dispatcher { self.active_id.set(context_id); stream.on_upstream_close(peer_type) } else { - panic!("invalid context_id") + maybe_panic!("on_upstream_close: invalid context_id") } } @@ -335,7 +360,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_request_headers(num_headers, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_http_request_headers: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -349,7 +376,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_request_body(body_size, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_http_request_body: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -358,7 +387,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_request_trailers(num_trailers) } else { - panic!("invalid context_id") + maybe_panic!("on_http_request_trailers: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -372,7 +403,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_response_headers(num_headers, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_http_response_headers: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -386,7 +419,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_response_body(body_size, end_of_stream) } else { - panic!("invalid context_id") + maybe_panic!("on_http_response_body: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -395,7 +430,9 @@ impl Dispatcher { self.active_id.set(context_id); http_stream.on_http_response_trailers(num_trailers) } else { - panic!("invalid context_id") + maybe_panic!("on_http_response_trailers: invalid context_id"); + #[allow(unreachable_code)] + Action::Continue } } @@ -406,24 +443,23 @@ impl Dispatcher { body_size: usize, num_trailers: usize, ) { - let context_id = self - .callouts - .borrow_mut() - .remove(&token_id) - .expect("invalid token_id"); - - if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { - self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); - http_stream.on_http_call_response(token_id, num_headers, body_size, num_trailers) - } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { - self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); - stream.on_http_call_response(token_id, num_headers, body_size, num_trailers) - } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { - self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); - root.on_http_call_response(token_id, num_headers, body_size, num_trailers) + let context_id = self.callouts.borrow_mut().remove(&token_id); + if let Some(context_id) = context_id { + if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { + self.active_id.set(context_id); + hostcalls::set_effective_context(context_id).unwrap_or(()); + http_stream.on_http_call_response(token_id, num_headers, body_size, num_trailers) + } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { + self.active_id.set(context_id); + hostcalls::set_effective_context(context_id).unwrap_or(()); + stream.on_http_call_response(token_id, num_headers, body_size, num_trailers) + } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { + self.active_id.set(context_id); + hostcalls::set_effective_context(context_id).unwrap_or(()); + root.on_http_call_response(token_id, num_headers, body_size, num_trailers) + } + } else { + maybe_panic!("on_http_call_response: invalid token_id") } } @@ -432,22 +468,22 @@ impl Dispatcher { Some(id) => *id, None => { // TODO: change back to a panic once underlying issue is fixed. - trace!("on_grpc_receive_initial_metadata: invalid token_id"); + dont_panic!("on_grpc_receive_initial_metadata: invalid token_id"); return; } }; if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_stream_initial_metadata(token_id, headers); } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_stream_initial_metadata(token_id, headers); } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_stream_initial_metadata(token_id, headers); } } @@ -457,15 +493,15 @@ impl Dispatcher { if let Some(context_id) = context_id { if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_call_response(token_id, 0, response_size); } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_call_response(token_id, 0, response_size); } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_call_response(token_id, 0, response_size); } } else { @@ -473,20 +509,20 @@ impl Dispatcher { if let Some(context_id) = context_id { if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_stream_message(token_id, response_size); } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_stream_message(token_id, response_size); } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_stream_message(token_id, response_size); } } else { // TODO: change back to a panic once underlying issue is fixed. - trace!("on_grpc_receive_initial_metadata: invalid token_id"); + dont_panic!("on_grpc_receive_initial_metadata: invalid token_id") } } } @@ -496,22 +532,22 @@ impl Dispatcher { Some(id) => *id, None => { // TODO: change back to a panic once underlying issue is fixed. - trace!("on_grpc_receive_trailing_metadata: invalid token_id"); + dont_panic!("on_grpc_receive_trailing_metadata: invalid token_id"); return; } }; if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_stream_trailing_metadata(token_id, trailers); } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_stream_trailing_metadata(token_id, trailers); } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_stream_trailing_metadata(token_id, trailers); } } @@ -521,15 +557,15 @@ impl Dispatcher { if let Some(context_id) = context_id { if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_call_response(token_id, status_code, 0); } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_call_response(token_id, status_code, 0); } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_call_response(token_id, status_code, 0); } } else { @@ -537,20 +573,20 @@ impl Dispatcher { if let Some(context_id) = context_id { if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_grpc_stream_close(token_id, status_code) } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_grpc_stream_close(token_id, status_code) } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_grpc_stream_close(token_id, status_code) } } else { // TODO: change back to a panic once underlying issue is fixed. - trace!("on_grpc_close: invalid token_id, a non-connected stream has closed"); + dont_panic!("on_grpc_close: invalid token_id, a non-connected stream has closed") } } } @@ -558,15 +594,15 @@ impl Dispatcher { fn on_foreign_function(&self, context_id: u32, function_id: u32, arugments_size: usize) { if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); http_stream.on_foreign_function(function_id, arugments_size) } else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); stream.on_foreign_function(function_id, arugments_size) } else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) { self.active_id.set(context_id); - hostcalls::set_effective_context(context_id).unwrap(); + hostcalls::set_effective_context(context_id).unwrap_or(()); root.on_foreign_function(function_id, arugments_size) } } diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 76c3513d..d2b10488 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -13,6 +13,7 @@ // limitations under the License. use crate::dispatcher; +use crate::maybe_panic; use crate::types::*; use std::ptr::{null, null_mut}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -25,7 +26,11 @@ pub fn log(level: LogLevel, message: &str) -> Result<(), Status> { unsafe { match proxy_log(level, message.as_ptr(), message.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_log unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -39,7 +44,11 @@ pub fn get_log_level() -> Result { unsafe { match proxy_get_log_level(&mut return_level) { Status::Ok => Ok(return_level), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_get_log_level unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -53,7 +62,14 @@ pub fn get_current_time() -> Result { unsafe { match proxy_get_current_time_nanoseconds(&mut return_time) { Status::Ok => Ok(UNIX_EPOCH + Duration::from_nanos(return_time)), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_current_time_nanoseconds unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -66,7 +82,14 @@ pub fn set_tick_period(period: Duration) -> Result<(), Status> { unsafe { match proxy_set_tick_period_milliseconds(period.as_millis() as u32) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_set_tick_period_milliseconds unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -108,7 +131,14 @@ pub fn get_buffer( } } Status::NotFound => Ok(None), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_buffer_bytes unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -132,7 +162,14 @@ pub fn set_buffer( unsafe { match proxy_set_buffer_bytes(buffer_type, start, size, value.as_ptr(), value.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_set_buffer_bytes unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -158,7 +195,14 @@ pub fn get_map(map_type: MapType) -> Result, Status> { Ok(Vec::new()) } } - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_header_map_pairs unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -176,7 +220,14 @@ pub fn get_map_bytes(map_type: MapType) -> Result, Status> Ok(Vec::new()) } } - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_header_map_pairs unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -194,7 +245,14 @@ pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> unsafe { match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_set_header_map_pairs unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -204,7 +262,14 @@ pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Result<(), S unsafe { match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_set_header_map_pairs unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -245,7 +310,14 @@ pub fn get_map_value(map_type: MapType, key: &str) -> Result, Sta } } Status::NotFound => Ok(None), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -273,7 +345,14 @@ pub fn get_map_value_bytes(map_type: MapType, key: &str) -> Result } } Status::NotFound => Ok(None), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_get_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -290,7 +369,14 @@ pub fn remove_map_value(map_type: MapType, key: &str) -> Result<(), Status> { unsafe { match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_remove_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -316,12 +402,26 @@ pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) -> Resul value.len(), ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_replace_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } else { match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_remove_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -342,12 +442,26 @@ pub fn set_map_value_bytes( value.len(), ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_replace_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } else { match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_remove_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -373,7 +487,14 @@ pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Result<(), St value.len(), ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_add_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -388,7 +509,14 @@ pub fn add_map_value_bytes(map_type: MapType, key: &str, value: &[u8]) -> Result value.len(), ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_add_header_map_value unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -427,7 +555,11 @@ pub fn get_property(path: Vec<&str>) -> Result, Status> { Status::NotFound => Ok(None), Status::SerializationFailure => Err(Status::SerializationFailure), Status::InternalFailure => Err(Status::InternalFailure), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_get_property unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -451,7 +583,11 @@ pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(), Status> value.map_or(0, |value| value.len()), ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_set_property unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -493,7 +629,11 @@ pub fn get_shared_data(key: &str) -> Result<(Option, Option), Status } } Status::NotFound => Ok((None, None)), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_get_shared_data unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -519,7 +659,11 @@ pub fn set_shared_data(key: &str, value: Option<&[u8]>, cas: Option) -> Res ) { Status::Ok => Ok(()), Status::CasMismatch => Err(Status::CasMismatch), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_set_shared_data unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -537,7 +681,14 @@ pub fn register_shared_queue(name: &str) -> Result { let mut return_id: u32 = 0; match proxy_register_shared_queue(name.as_ptr(), name.len(), &mut return_id) { Status::Ok => Ok(return_id), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_register_shared_queue unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -564,7 +715,14 @@ pub fn resolve_shared_queue(vm_id: &str, name: &str) -> Result, Stat ) { Status::Ok => Ok(Some(return_id)), Status::NotFound => Ok(None), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_resolve_shared_queue unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -595,7 +753,14 @@ pub fn dequeue_shared_queue(queue_id: u32) -> Result, Status> { } Status::Empty => Ok(None), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_dequeue_shared_queue unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -617,7 +782,14 @@ pub fn enqueue_shared_queue(queue_id: u32, value: Option<&[u8]>) -> Result<(), S ) { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_enqueue_shared_queue unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -630,7 +802,11 @@ pub fn resume_downstream() -> Result<(), Status> { unsafe { match proxy_continue_stream(StreamType::Downstream) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_continue_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -639,7 +815,11 @@ pub fn resume_upstream() -> Result<(), Status> { unsafe { match proxy_continue_stream(StreamType::Upstream) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_continue_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -648,7 +828,11 @@ pub fn resume_http_request() -> Result<(), Status> { unsafe { match proxy_continue_stream(StreamType::HttpRequest) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_continue_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -657,7 +841,11 @@ pub fn resume_http_response() -> Result<(), Status> { unsafe { match proxy_continue_stream(StreamType::HttpResponse) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_continue_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -670,7 +858,11 @@ pub fn close_downstream() -> Result<(), Status> { unsafe { match proxy_close_stream(StreamType::Downstream) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_close_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -678,7 +870,11 @@ pub fn close_upstream() -> Result<(), Status> { unsafe { match proxy_close_stream(StreamType::Upstream) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_close_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -687,7 +883,11 @@ pub fn reset_http_request() -> Result<(), Status> { unsafe { match proxy_close_stream(StreamType::HttpRequest) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_close_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -696,7 +896,11 @@ pub fn reset_http_response() -> Result<(), Status> { unsafe { match proxy_close_stream(StreamType::HttpResponse) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_close_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -732,7 +936,14 @@ pub fn send_http_response( -1, ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_send_local_response unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -755,7 +966,14 @@ pub fn send_grpc_response( grpc_status as i32, ) { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_send_local_response unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -804,7 +1022,11 @@ pub fn dispatch_http_call( } Status::BadArgument => Err(Status::BadArgument), Status::InternalFailure => Err(Status::InternalFailure), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_http_call unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -857,7 +1079,11 @@ pub fn dispatch_grpc_call( } Status::ParseFailure => Err(Status::ParseFailure), Status::InternalFailure => Err(Status::InternalFailure), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_call unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -902,7 +1128,11 @@ pub fn open_grpc_stream( } Status::ParseFailure => Err(Status::ParseFailure), Status::InternalFailure => Err(Status::InternalFailure), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_stream unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -931,7 +1161,11 @@ pub fn send_grpc_stream_message( Status::Ok => Ok(()), Status::BadArgument => Err(Status::BadArgument), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_send unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -945,7 +1179,11 @@ pub fn cancel_grpc_call(token_id: u32) -> Result<(), Status> { match proxy_grpc_cancel(token_id) { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_cancel unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -955,7 +1193,11 @@ pub fn cancel_grpc_stream(token_id: u32) -> Result<(), Status> { match proxy_grpc_cancel(token_id) { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_cancel unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -969,7 +1211,11 @@ pub fn close_grpc_stream(token_id: u32) -> Result<(), Status> { match proxy_grpc_close(token_id) { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_grpc_close unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1005,7 +1251,11 @@ pub fn get_grpc_status() -> Result<(u32, Option), Status> { Ok((return_code, None)) } } - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_get_status unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1019,7 +1269,14 @@ pub fn set_effective_context(context_id: u32) -> Result<(), Status> { match proxy_set_effective_context(context_id) { Status::Ok => Ok(()), Status::BadArgument => Err(Status::BadArgument), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_set_effective_context unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1065,7 +1322,14 @@ pub fn call_foreign_function( Status::BadArgument => Err(Status::BadArgument), Status::SerializationFailure => Err(Status::SerializationFailure), Status::InternalFailure => Err(Status::InternalFailure), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_call_foreign_function unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1078,7 +1342,11 @@ pub fn done() -> Result<(), Status> { unsafe { match proxy_done() { Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_done unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1097,7 +1365,11 @@ pub fn define_metric(metric_type: MetricType, name: &str) -> Result unsafe { match proxy_define_metric(metric_type, name.as_ptr(), name.len(), &mut return_id) { Status::Ok => Ok(return_id), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_define_metric unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1113,7 +1385,11 @@ pub fn get_metric(metric_id: u32) -> Result { Status::Ok => Ok(return_value), Status::NotFound => Err(Status::NotFound), Status::BadArgument => Err(Status::BadArgument), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_get_metric unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1127,7 +1403,11 @@ pub fn record_metric(metric_id: u32, value: u64) -> Result<(), Status> { match proxy_record_metric(metric_id, value) { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!("proxy_record_metric unexpected status: {}", status as u32); + #[allow(unreachable_code)] + Err(status) + } } } } @@ -1142,7 +1422,14 @@ pub fn increment_metric(metric_id: u32, offset: i64) -> Result<(), Status> { Status::Ok => Ok(()), Status::NotFound => Err(Status::NotFound), Status::BadArgument => Err(Status::BadArgument), - status => panic!("unexpected status: {}", status as u32), + status => { + maybe_panic!( + "proxy_increment_metric unexpected status: {}", + status as u32 + ); + #[allow(unreachable_code)] + Err(status) + } } } } diff --git a/src/logger.rs b/src/logger.rs index 050a356d..97a3b765 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -17,6 +17,23 @@ use crate::types::LogLevel; use std::panic; use std::sync::atomic::{AtomicBool, Ordering}; +#[cfg(not(feature = "no-panic"))] +#[macro_export] +macro_rules! maybe_panic { + ($($arg:tt)*) => { panic!($($arg)*) }; +} + +#[cfg(feature = "no-panic")] +#[macro_export] +macro_rules! maybe_panic { + ($($arg:tt)*) => { $crate::hostcalls::log(LogLevel::Critical, format!($($arg)*).as_str()).unwrap_or(()) }; +} + +#[macro_export] +macro_rules! dont_panic { + ($($arg:tt)*) => { $crate::hostcalls::log(LogLevel::Critical, format!($($arg)*).as_str()).unwrap_or(()) }; +} + struct Logger; static LOGGER: Logger = Logger;