feat: harden community production foundation through story 1.5

This commit is contained in:
2026-08-14 00:21:59 +03:00
parent c30461cc92
commit f6fc2e5c9b
161 changed files with 16758 additions and 2515 deletions
+44 -14
View File
@@ -74,9 +74,9 @@ impl ApiError {
}
}
pub fn internal(message: impl Into<String>) -> Self {
pub fn internal(_message: impl Into<String>) -> Self {
Self::Internal {
message: message.into(),
message: "internal server error".to_owned(),
context: None,
}
}
@@ -165,6 +165,13 @@ impl IntoResponse for ApiError {
if let Some(context) = self.context() {
error["context"] = context;
}
let (request_id, trace_id) = crank_observability::current_request_correlation();
if let Some(request_id) = request_id {
error["request_id"] = Value::String(request_id);
}
if let Some(trace_id) = trace_id {
error["trace_id"] = Value::String(trace_id);
}
let body = Json(json!({
"error": error
@@ -363,9 +370,10 @@ impl From<RegistryError> for ApiError {
format!("import job {job_id} was already applied with different parameters"),
json!({ "job_id": job_id }),
),
RegistryError::Storage(_) | RegistryError::Serialization(_) => {
Self::internal(value.to_string())
}
RegistryError::Migration(_)
| RegistryError::Storage(_)
| RegistryError::Serialization(_)
| RegistryError::InvalidCorrelationIdentity { .. } => Self::internal(value.to_string()),
}
}
}
@@ -399,7 +407,7 @@ impl From<StorageError> for ApiError {
pub fn runtime_test_failure(error: &RuntimeError) -> Value {
let mut payload = json!({
"code": runtime_test_failure_code(error),
"message": error.to_string()
"message": safe_runtime_test_failure_message(error)
});
if let Some(context) = runtime_error_context(error) {
payload["context"] = context;
@@ -407,6 +415,33 @@ pub fn runtime_test_failure(error: &RuntimeError) -> Value {
payload
}
fn safe_runtime_test_failure_message(error: &RuntimeError) -> &'static str {
match error {
RuntimeError::Schema(_) => "input schema validation failed",
RuntimeError::Mapping(_) => "input mapping failed",
RuntimeError::RestAdapter(_) | RuntimeError::ProtocolAdapter(_) => {
"upstream execution failed"
}
RuntimeError::UnsupportedProtocol { .. } => "operation protocol is unsupported",
RuntimeError::ConcurrencyLimitExceeded { .. } => "runtime concurrency limit exceeded",
RuntimeError::InvalidPreparedRequest { .. } => "prepared request is invalid",
RuntimeError::ConfirmationRequired { .. } => "operation confirmation is required",
RuntimeError::InvalidConfirmationToken { .. } => "confirmation token is invalid",
RuntimeError::ConfirmationStoreUnavailable { .. } => "confirmation store is unavailable",
RuntimeError::IdempotencyStoreUnavailable { .. } => "idempotency store is unavailable",
RuntimeError::IdempotencyInProgress { .. } => "idempotent execution is in progress",
RuntimeError::IdempotencyConflict { .. } => "idempotency key conflicts with the request",
RuntimeError::IdempotencyOutcomeUnknown { .. } => "previous execution outcome is unknown",
RuntimeError::UnsupportedExecutionMode { .. } => "execution mode is unsupported",
RuntimeError::MissingAuthProfile { .. } => "authorization profile is missing",
RuntimeError::MissingSecret { .. } | RuntimeError::MissingSecretVersion { .. } => {
"authorization secret is missing"
}
RuntimeError::InvalidAuthSecretValue { .. } => "authorization secret is invalid",
RuntimeError::SecretCrypto { .. } => "authorization secret processing failed",
}
}
fn runtime_test_failure_code(error: &RuntimeError) -> &'static str {
match error {
RuntimeError::Schema(_) => "runtime_schema_error",
@@ -435,9 +470,8 @@ fn runtime_test_failure_code(error: &RuntimeError) -> &'static str {
pub fn runtime_error_context(error: &RuntimeError) -> Option<Value> {
match error {
RuntimeError::InvalidPreparedRequest { field, reason } => Some(json!({
RuntimeError::InvalidPreparedRequest { field, .. } => Some(json!({
"field": field,
"reason": reason,
})),
RuntimeError::ConfirmationRequired {
confirmation_token,
@@ -457,14 +491,10 @@ pub fn runtime_error_context(error: &RuntimeError) -> Option<Value> {
| RuntimeError::IdempotencyOutcomeUnknown { operation_id } => Some(json!({
"operation_id": operation_id,
})),
RuntimeError::InvalidAuthSecretValue { secret_id, reason } => Some(json!({
RuntimeError::InvalidAuthSecretValue { secret_id, .. } => Some(json!({
"secret_id": secret_id,
"reason": reason,
})),
RuntimeError::SecretCrypto { operation, details } => Some(json!({
"operation": operation,
"details": details,
})),
RuntimeError::SecretCrypto { .. } => None,
RuntimeError::MissingAuthProfile { auth_profile_id } => Some(json!({
"auth_profile_id": auth_profile_id,
})),