improve errors for CEL input

This commit is contained in:
aecsocket
2026-08-12 08:12:44 +00:00
parent 7f59feeb98
commit 04d00c0ba0
10 changed files with 183 additions and 109 deletions
@@ -1417,7 +1417,7 @@ pub async fn update_issue_details(
security(("bearer_auth" = [])),
responses((status = NO_CONTENT))
)]
#[post("/global-issue-detail")]
#[post("/global-traces")]
pub async fn update_global_issue_details(
req: HttpRequest,
pool: web::Data<PgPool>,
@@ -133,7 +133,7 @@ pub struct GlobalIssueDetailTrace {
security(("bearer_auth" = [])),
responses((status = OK, body = SearchGlobalIssueDetailsResponse))
)]
#[post("/global-issue-detail/search")]
#[post("/global-traces/search")]
pub async fn search_global_issue_details(
req: HttpRequest,
pool: web::Data<PgPool>,
@@ -357,7 +357,7 @@ pub async fn search_global_issue_details(
security(("bearer_auth" = [])),
responses((status = OK, body = GetGlobalIssueDetailResponse))
)]
#[post("/global-issue-detail/local-traces")]
#[post("/global-traces/local-traces")]
pub async fn get_global_issue_detail(
req: HttpRequest,
pool: web::Data<PgPool>,
@@ -115,7 +115,9 @@ impl WriteDelphiRule {
.await
.wrap_internal_err("failed to join cel compilation task")?
.map_err(|error| {
ApiError::Request(eyre!("invalid cel expression: {error}"))
ApiError::Request(
eyre!(error).wrap_err("invalid cel expression"),
)
})?;
Ok(ValidatedRule {
@@ -165,7 +167,9 @@ pub async fn test_rule(
.await
.wrap_internal_err("failed to join cel compilation task")?
.map_err(|error| {
ApiError::Request(eyre!("invalid cel expression: {error}"))
ApiError::Request(
eyre!(error).wrap_err("invalid cel expression"),
)
})?;
let mut effects = Vec::with_capacity(request.inputs.len());
+41 -2
View File
@@ -235,6 +235,23 @@ impl ApiError {
}
pub fn as_api_error<'a>(&self) -> crate::models::error::ApiError<'a> {
let report = match self {
Self::Internal(report)
| Self::Request(report)
| Self::Auth(report)
| Self::NotFound(report)
| Self::Conflict(report)
| Self::FailedDependency(report)
| Self::PreconditionRequired(report)
| Self::PreconditionFailed(report)
| Self::RateLimit(report) => report,
};
let details = report
.chain()
.skip(1)
.map(ToString::to_string)
.collect::<Vec<_>>();
crate::models::error::ApiError {
error: match self {
Self::Internal(..) => "internal_error",
@@ -247,8 +264,8 @@ impl ApiError {
Self::PreconditionFailed(..) => "precondition_failed",
Self::RateLimit(..) => "ratelimit_error",
},
description: format!("{self:#}"),
details: None,
description: report.to_string(),
details: (!details.is_empty()).then(|| serde_json::json!(details)),
}
}
}
@@ -272,3 +289,25 @@ impl actix_web::ResponseError for ApiError {
HttpResponse::build(self.status_code()).json(self.as_api_error())
}
}
#[cfg(test)]
mod tests {
use super::ApiError;
#[test]
fn api_error_serializes_source_chain_as_details() {
let error = ApiError::Request(
eyre::eyre!("root cause")
.wrap_err("intermediate context")
.wrap_err("request failed"),
);
let response = error.as_api_error();
assert_eq!(response.description, "request failed");
assert_eq!(
response.details,
Some(serde_json::json!(["intermediate context", "root cause"])),
);
}
}