lambda_microvm_hook_server/
error.rs1use crate::state::HookServerState;
2use axum::Json;
3use axum::http::StatusCode;
4use axum::response::{IntoResponse, Response};
5use serde_json::{Value, json};
6use std::io;
7
8#[derive(Debug, thiserror::Error)]
9pub enum MicroVmError {
10 #[error("failed to bind hook server: {0}")]
11 Bind(#[source] io::Error),
12 #[error("hook server failed: {0}")]
13 Server(#[source] io::Error),
14 #[error("invalid log filter: {0}")]
15 InvalidLogFilter(#[source] tracing_subscriber::filter::ParseError),
16 #[error("failed to start run command: {0}")]
17 CommandSpawn(#[source] io::Error),
18 #[error("failed while waiting for run command: {0}")]
19 CommandWait(#[source] io::Error),
20 #[error("run command reported failure")]
21 CommandFailed,
22}
23
24pub(crate) struct ApiError {
25 status: StatusCode,
26 message: String,
27}
28
29impl ApiError {
30 pub(crate) fn bad_request(message: impl Into<String>) -> Self {
31 Self { status: StatusCode::BAD_REQUEST, message: message.into() }
32 }
33
34 pub(crate) fn conflict(message: impl Into<String>) -> Self {
35 Self { status: StatusCode::CONFLICT, message: message.into() }
36 }
37
38 pub(crate) fn initialization(state: &HookServerState, error: MicroVmError) -> Self {
39 let message = error.to_string();
40 state.finish(Err(error));
41 Self { status: StatusCode::INTERNAL_SERVER_ERROR, message }
42 }
43}
44
45impl IntoResponse for ApiError {
46 fn into_response(self) -> Response {
47 error_response(self.status, &self.message)
48 }
49}
50
51pub(crate) fn error_response(status: StatusCode, message: &str) -> Response {
52 let body: Value = json!({ "error": message });
53 (status, Json(body)).into_response()
54}