api: add structured context for service errors
This commit is contained in:
@@ -1611,7 +1611,10 @@ impl AdminService {
|
||||
) -> Result<AsyncJobDetailView, ApiError> {
|
||||
self.ensure_workspace_exists(workspace_id).await?;
|
||||
let job = self.registry.get_async_job(job_id).await?.ok_or_else(|| {
|
||||
ApiError::not_found(format!("async job {} was not found", job_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("async job {} was not found", job_id.as_str()),
|
||||
json!({ "job_id": job_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
ensure_async_job_workspace(&job, workspace_id)?;
|
||||
|
||||
@@ -1626,14 +1629,20 @@ impl AdminService {
|
||||
) -> Result<AsyncJobDetailView, ApiError> {
|
||||
self.ensure_workspace_exists(workspace_id).await?;
|
||||
let job = self.registry.get_async_job(job_id).await?.ok_or_else(|| {
|
||||
ApiError::not_found(format!("async job {} was not found", job_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("async job {} was not found", job_id.as_str()),
|
||||
json!({ "job_id": job_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
ensure_async_job_workspace(&job, workspace_id)?;
|
||||
self.registry
|
||||
.cancel_async_job(job_id, &OffsetDateTime::now_utc())
|
||||
.await?;
|
||||
let updated = self.registry.get_async_job(job_id).await?.ok_or_else(|| {
|
||||
ApiError::not_found(format!("async job {} was not found", job_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("async job {} was not found", job_id.as_str()),
|
||||
json!({ "job_id": job_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(async_job_detail_view(updated))
|
||||
@@ -1647,15 +1656,44 @@ impl AdminService {
|
||||
) -> Result<Value, ApiError> {
|
||||
self.ensure_workspace_exists(workspace_id).await?;
|
||||
let job = self.registry.get_async_job(job_id).await?.ok_or_else(|| {
|
||||
ApiError::not_found(format!("async job {} was not found", job_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("async job {} was not found", job_id.as_str()),
|
||||
json!({ "job_id": job_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
ensure_async_job_workspace(&job, workspace_id)?;
|
||||
|
||||
match job.status {
|
||||
JobStatus::Completed => Ok(job.result.unwrap_or(Value::Null)),
|
||||
JobStatus::Failed => Err(ApiError::conflict("async job failed")),
|
||||
JobStatus::Cancelled => Err(ApiError::conflict("async job was cancelled")),
|
||||
_ => Err(ApiError::conflict("async job result is not ready")),
|
||||
JobStatus::Failed => Err(ApiError::conflict_with_context(
|
||||
"async job failed",
|
||||
json!({
|
||||
"job_id": job_id.as_str(),
|
||||
"status": "failed",
|
||||
"error": job.error,
|
||||
}),
|
||||
)),
|
||||
JobStatus::Cancelled => Err(ApiError::conflict_with_context(
|
||||
"async job was cancelled",
|
||||
json!({
|
||||
"job_id": job_id.as_str(),
|
||||
"status": "cancelled",
|
||||
}),
|
||||
)),
|
||||
_ => Err(ApiError::conflict_with_context(
|
||||
"async job result is not ready",
|
||||
json!({
|
||||
"job_id": job_id.as_str(),
|
||||
"status": match job.status {
|
||||
JobStatus::Created => "created",
|
||||
JobStatus::Running => "running",
|
||||
JobStatus::Completed => "completed",
|
||||
JobStatus::Failed => "failed",
|
||||
JobStatus::Cancelled => "cancelled",
|
||||
JobStatus::Expired => "expired",
|
||||
},
|
||||
}),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3055,7 +3093,16 @@ impl AdminService {
|
||||
.find(|descriptor| {
|
||||
descriptor.descriptor_kind == crank_registry::DescriptorKind::DescriptorSet
|
||||
})
|
||||
.ok_or_else(|| ApiError::not_found("descriptor set was not uploaded"))?;
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found_with_context(
|
||||
"descriptor set was not uploaded",
|
||||
json!({
|
||||
"operation_id": operation_id.as_str(),
|
||||
"version": version,
|
||||
"descriptor_kind": "descriptor_set",
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
let bytes = self.storage.read_bytes(&descriptor.storage_ref).await?;
|
||||
let services = services_from_descriptor_set_bytes(&bytes)
|
||||
.map_err(|error| ApiError::validation(error.to_string()))?;
|
||||
@@ -3207,10 +3254,26 @@ impl AdminService {
|
||||
.find(|descriptor| {
|
||||
descriptor.descriptor_kind == crank_registry::DescriptorKind::WsdlUpload
|
||||
})
|
||||
.ok_or_else(|| ApiError::not_found("wsdl was not uploaded"))?;
|
||||
let package_index = descriptor
|
||||
.package_index
|
||||
.ok_or_else(|| ApiError::not_found("wsdl inspection metadata is not available"))?;
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found_with_context(
|
||||
"wsdl was not uploaded",
|
||||
json!({
|
||||
"operation_id": operation_id.as_str(),
|
||||
"version": version,
|
||||
"descriptor_kind": "wsdl_upload",
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
let package_index = descriptor.package_index.ok_or_else(|| {
|
||||
ApiError::not_found_with_context(
|
||||
"wsdl inspection metadata is not available",
|
||||
json!({
|
||||
"operation_id": operation_id.as_str(),
|
||||
"version": version,
|
||||
"descriptor_kind": "wsdl_upload",
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
|
||||
serde_json::from_value(package_index).map_err(|error| ApiError::internal(error.to_string()))
|
||||
}
|
||||
@@ -3225,10 +3288,10 @@ impl AdminService {
|
||||
.get_auth_profile(workspace_id, auth_profile_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!(
|
||||
"auth profile {} was not found",
|
||||
auth_profile_id.as_str()
|
||||
))
|
||||
ApiError::not_found_with_context(
|
||||
format!("auth profile {} was not found", auth_profile_id.as_str()),
|
||||
json!({ "auth_profile_id": auth_profile_id.as_str() }),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user