Skip to main content

lambda_microvm_hook_server/
error.rs

1use 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}