api: finish structured error normalization
This commit is contained in:
@@ -69,20 +69,6 @@ impl ApiError {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn not_found(message: impl Into<String>) -> Self {
|
||||
Self::NotFound {
|
||||
message: message.into(),
|
||||
context: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn conflict(message: impl Into<String>) -> Self {
|
||||
Self::Conflict {
|
||||
message: message.into(),
|
||||
context: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn internal(message: impl Into<String>) -> Self {
|
||||
Self::Internal {
|
||||
message: message.into(),
|
||||
|
||||
@@ -961,7 +961,12 @@ impl AdminService {
|
||||
.registry
|
||||
.get_auth_user_by_id(user_id)
|
||||
.await?
|
||||
.ok_or_else(|| ApiError::not_found(format!("user {} was not found", user_id.as_str())))?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found_with_context(
|
||||
format!("user {} was not found", user_id.as_str()),
|
||||
json!({ "user_id": user_id.as_str() }),
|
||||
)
|
||||
})?
|
||||
.user;
|
||||
let memberships = self.registry.list_workspaces_for_user(user_id).await?;
|
||||
|
||||
@@ -988,7 +993,10 @@ impl AdminService {
|
||||
.get_auth_user_by_id(user_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!("user {} was not found", user_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("user {} was not found", user_id.as_str()),
|
||||
json!({ "user_id": user_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !verify_password(
|
||||
@@ -1016,7 +1024,10 @@ impl AdminService {
|
||||
.get_workspace(workspace_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!("workspace {} was not found", workspace_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("workspace {} was not found", workspace_id.as_str()),
|
||||
json!({ "workspace_id": workspace_id.as_str() }),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1071,11 +1082,17 @@ impl AdminService {
|
||||
.iter()
|
||||
.find(|membership| &membership.user.id == target_user_id)
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!(
|
||||
"membership for user {} in workspace {} was not found",
|
||||
target_user_id.as_str(),
|
||||
workspace_id.as_str()
|
||||
))
|
||||
ApiError::not_found_with_context(
|
||||
format!(
|
||||
"membership for user {} in workspace {} was not found",
|
||||
target_user_id.as_str(),
|
||||
workspace_id.as_str()
|
||||
),
|
||||
json!({
|
||||
"workspace_id": workspace_id.as_str(),
|
||||
"user_id": target_user_id.as_str(),
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !matches!(
|
||||
@@ -1122,11 +1139,17 @@ impl AdminService {
|
||||
.iter()
|
||||
.find(|membership| &membership.user.id == target_user_id)
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!(
|
||||
"membership for user {} in workspace {} was not found",
|
||||
target_user_id.as_str(),
|
||||
workspace_id.as_str()
|
||||
))
|
||||
ApiError::not_found_with_context(
|
||||
format!(
|
||||
"membership for user {} in workspace {} was not found",
|
||||
target_user_id.as_str(),
|
||||
workspace_id.as_str()
|
||||
),
|
||||
json!({
|
||||
"workspace_id": workspace_id.as_str(),
|
||||
"user_id": target_user_id.as_str(),
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
|
||||
if !matches!(
|
||||
@@ -1826,10 +1849,10 @@ impl AdminService {
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Err(ApiError::conflict(format!(
|
||||
"operation with name {} already exists",
|
||||
payload.name
|
||||
)));
|
||||
return Err(ApiError::conflict_with_context(
|
||||
format!("operation with name {} already exists", payload.name),
|
||||
json!({ "name": payload.name }),
|
||||
));
|
||||
}
|
||||
|
||||
let now = OffsetDateTime::now_utc();
|
||||
@@ -1888,7 +1911,10 @@ impl AdminService {
|
||||
.get_operation_summary(workspace_id, operation_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!("operation {} was not found", operation_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("operation {} was not found", operation_id.as_str()),
|
||||
json!({ "operation_id": operation_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let version = summary.current_draft_version + 1;
|
||||
@@ -2757,10 +2783,10 @@ impl AdminService {
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Err(ApiError::conflict(format!(
|
||||
"agent with slug {} already exists",
|
||||
payload.slug
|
||||
)));
|
||||
return Err(ApiError::conflict_with_context(
|
||||
format!("agent with slug {} already exists", payload.slug),
|
||||
json!({ "slug": payload.slug }),
|
||||
));
|
||||
}
|
||||
|
||||
let now = OffsetDateTime::now_utc();
|
||||
@@ -2816,7 +2842,10 @@ impl AdminService {
|
||||
.get_agent_summary(workspace_id, agent_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!("agent {} was not found", agent_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("agent {} was not found", agent_id.as_str()),
|
||||
json!({ "agent_id": agent_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
|
||||
if payload.slug != existing.slug
|
||||
@@ -2825,10 +2854,10 @@ impl AdminService {
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Err(ApiError::conflict(format!(
|
||||
"agent with slug {} already exists",
|
||||
payload.slug
|
||||
)));
|
||||
return Err(ApiError::conflict_with_context(
|
||||
format!("agent with slug {} already exists", payload.slug),
|
||||
json!({ "slug": payload.slug }),
|
||||
));
|
||||
}
|
||||
|
||||
let updated_at = OffsetDateTime::now_utc();
|
||||
@@ -2861,7 +2890,10 @@ impl AdminService {
|
||||
.get_agent_summary(workspace_id, agent_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
ApiError::not_found(format!("agent {} was not found", agent_id.as_str()))
|
||||
ApiError::not_found_with_context(
|
||||
format!("agent {} was not found", agent_id.as_str()),
|
||||
json!({ "agent_id": agent_id.as_str() }),
|
||||
)
|
||||
})?;
|
||||
|
||||
self.registry.delete_agent(workspace_id, agent_id).await?;
|
||||
@@ -4924,11 +4956,17 @@ fn ensure_stream_session_workspace(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(ApiError::not_found(format!(
|
||||
"stream session {} was not found in workspace {}",
|
||||
session.id.as_str(),
|
||||
workspace_id.as_str()
|
||||
)))
|
||||
Err(ApiError::not_found_with_context(
|
||||
format!(
|
||||
"stream session {} was not found in workspace {}",
|
||||
session.id.as_str(),
|
||||
workspace_id.as_str()
|
||||
),
|
||||
json!({
|
||||
"session_id": session.id.as_str(),
|
||||
"workspace_id": workspace_id.as_str(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
fn ensure_async_job_workspace(
|
||||
@@ -4939,11 +4977,17 @@ fn ensure_async_job_workspace(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(ApiError::not_found(format!(
|
||||
"async job {} was not found in workspace {}",
|
||||
job.id.as_str(),
|
||||
workspace_id.as_str()
|
||||
)))
|
||||
Err(ApiError::not_found_with_context(
|
||||
format!(
|
||||
"async job {} was not found in workspace {}",
|
||||
job.id.as_str(),
|
||||
workspace_id.as_str()
|
||||
),
|
||||
json!({
|
||||
"job_id": job.id.as_str(),
|
||||
"workspace_id": workspace_id.as_str(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
fn usage_window(period: UsagePeriod) -> Result<(UsagePeriod, String, UsageBucket), ApiError> {
|
||||
|
||||
Reference in New Issue
Block a user