athena_rs 3.22.1

Hyper performant polyglot Database driver
Documentation
use actix_web::HttpResponse;
use actix_web::http::StatusCode;
use serde_json::Value;
use serde_json::json;

use crate::api::gateway::contracts::GatewayOperationKind;
use athena_gateway::GatewayErrorEnvelope;
pub use athena_gateway::{
    GATEWAY_ERROR_CODE_BACKEND_TEMPORARILY_UNAVAILABLE, GATEWAY_ERROR_CODE_BACKEND_UNAVAILABLE,
    GATEWAY_ERROR_CODE_CLIENT_CATALOG_UNAVAILABLE, GATEWAY_ERROR_CODE_CLIENT_FROZEN,
    GATEWAY_ERROR_CODE_CLIENT_INACTIVE, GATEWAY_ERROR_CODE_CLIENT_LOOKUP_FAILED,
    GATEWAY_ERROR_CODE_D1_BACKEND_UNAVAILABLE, GATEWAY_ERROR_CODE_DEFERRED_QUERY_NOT_SUPPORTED,
    GATEWAY_ERROR_CODE_DEFERRED_QUEUE_UNAVAILABLE, GATEWAY_ERROR_CODE_DELETE_EXECUTION_FAILED,
    GATEWAY_ERROR_CODE_EMPTY_QUERY, GATEWAY_ERROR_CODE_FETCH_DATA_FAILED,
    GATEWAY_ERROR_CODE_FETCH_DELEGATION_FAILED,
    GATEWAY_ERROR_CODE_FETCH_RESPONSE_PROCESSING_FAILED,
    GATEWAY_ERROR_CODE_INSERT_WINDOW_RESPONSE_CHANNEL_DROPPED, GATEWAY_ERROR_CODE_INTERNAL_ERROR,
    GATEWAY_ERROR_CODE_INVALID_CLIENT, GATEWAY_ERROR_CODE_INVALID_CLIENT_METADATA,
    GATEWAY_ERROR_CODE_INVALID_CONDITION_VALUE, GATEWAY_ERROR_CODE_INVALID_DELETE_PAYLOAD,
    GATEWAY_ERROR_CODE_INVALID_DELETE_RESOURCE_ID_COLUMN,
    GATEWAY_ERROR_CODE_INVALID_FETCH_CONDITION, GATEWAY_ERROR_CODE_INVALID_INSERT_PAYLOAD,
    GATEWAY_ERROR_CODE_INVALID_POST_PROCESSING_CONFIGURATION,
    GATEWAY_ERROR_CODE_INVALID_QUERY_PAYLOAD,
    GATEWAY_ERROR_CODE_INVALID_RELATION_SELECT_COMPATIBILITY_QUERY,
    GATEWAY_ERROR_CODE_INVALID_ROUTE_TARGET, GATEWAY_ERROR_CODE_INVALID_SCHEMA_NAME,
    GATEWAY_ERROR_CODE_INVALID_SCHEMA_TABLE_SELECTOR,
    GATEWAY_ERROR_CODE_INVALID_STRUCTURED_SELECT_REQUEST,
    GATEWAY_ERROR_CODE_MALFORMED_JSON_PAYLOAD, GATEWAY_ERROR_CODE_MISSING_CLIENT_HEADER,
    GATEWAY_ERROR_CODE_MISSING_CONDITIONS, GATEWAY_ERROR_CODE_MISSING_EQ_COLUMN_PARAMETER,
    GATEWAY_ERROR_CODE_MISSING_EQ_VALUE_PARAMETER, GATEWAY_ERROR_CODE_MISSING_ORGANIZATION_HEADER,
    GATEWAY_ERROR_CODE_MISSING_REQUEST_BODY, GATEWAY_ERROR_CODE_MISSING_RESOURCE_ID,
    GATEWAY_ERROR_CODE_MISSING_TABLE_NAME, GATEWAY_ERROR_CODE_MISSING_UPDATE_PAYLOAD,
    GATEWAY_ERROR_CODE_MISSING_VIEW_PARAMETER, GATEWAY_ERROR_CODE_OUTBOUND_REQUEST_RATE_LIMITED,
    GATEWAY_ERROR_CODE_QUERY_BACKEND_UNAVAILABLE, GATEWAY_ERROR_CODE_QUERY_EXECUTION_FAILED,
    GATEWAY_ERROR_CODE_QUERY_SQL_EXECUTION_FAILED, GATEWAY_ERROR_CODE_ROUTE_TARGET_LOOP_DETECTED,
    GATEWAY_ERROR_CODE_ROUTE_TARGET_RESPONSE_UNAVAILABLE,
    GATEWAY_ERROR_CODE_ROUTE_TARGET_UNAVAILABLE, GATEWAY_ERROR_CODE_SCYLLA_BACKEND_UNAVAILABLE,
    GATEWAY_ERROR_CODE_SERVICE_UNAVAILABLE, GATEWAY_ERROR_CODE_SUPABASE_CLIENT_RESOLUTION_FAILED,
    GATEWAY_ERROR_CODE_UNSUPPORTED_GATEWAY_FETCH_SHAPE, GATEWAY_ERROR_CODE_UNSUPPORTED_SCHEMA_NAME,
    GATEWAY_ERROR_CODE_VALIDATION_FAILED,
};

pub fn gateway_error_with_details(
    status: StatusCode,
    code: impl Into<String>,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
    details: Option<Value>,
) -> HttpResponse {
    HttpResponse::build(status).json(GatewayErrorEnvelope::new(
        code, operation, message, error, details,
    ))
}

pub fn gateway_bad_request_with_details(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
    details: Option<Value>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::BAD_REQUEST,
        GATEWAY_ERROR_CODE_VALIDATION_FAILED,
        operation,
        message,
        error,
        details,
    )
}

pub fn gateway_bad_request_with_code_and_details(
    code: impl Into<String>,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
    details: Option<Value>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::BAD_REQUEST,
        code,
        operation,
        message,
        error,
        details,
    )
}

pub fn gateway_bad_request_with_code(
    code: impl Into<String>,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_bad_request_with_code_and_details(code, operation, message, error, None)
}

pub fn gateway_bad_request(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_bad_request_with_details(operation, message, error, None)
}

pub fn gateway_internal_error_with_code(
    code: impl Into<String>,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::INTERNAL_SERVER_ERROR,
        code,
        operation,
        message,
        error,
        None,
    )
}

pub fn gateway_internal_error(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::INTERNAL_SERVER_ERROR,
        GATEWAY_ERROR_CODE_INTERNAL_ERROR,
        operation,
        message,
        error,
        None,
    )
}

pub fn gateway_service_unavailable_with_code(
    code: impl Into<String>,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::SERVICE_UNAVAILABLE,
        code,
        operation,
        message,
        error,
        None,
    )
}

pub fn gateway_service_unavailable(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::SERVICE_UNAVAILABLE,
        GATEWAY_ERROR_CODE_SERVICE_UNAVAILABLE,
        operation,
        message,
        error,
        None,
    )
}

pub fn missing_client_header_response(operation: GatewayOperationKind) -> HttpResponse {
    gateway_bad_request_with_code_and_details(
        GATEWAY_ERROR_CODE_MISSING_CLIENT_HEADER,
        operation,
        "Missing required header",
        "X-Athena-Client header or x-pg-uri is required and cannot be empty",
        Some(json!({
            "missing_header": "X-Athena-Client or x-pg-uri"
        })),
    )
}