fix: align protocol error semantics

This commit is contained in:
2026-09-30 05:26:34 +09:00
parent 75119f23e5
commit 027555eb4e
9 changed files with 323 additions and 47 deletions
+10 -6
View File
@@ -545,9 +545,9 @@ pub trait ObjectProvider {
self.with_object(path, PublishedObject::protocol_object)
.ok_or_else(|| CallError::new(CallErrorKind::NotFound, "target path is not published"))
.and_then(|object| {
object.validate_at_path(path).map_err(|error| {
CallError::new(CallErrorKind::InvalidResult, error.to_string())
})?;
object
.validate_at_path(path)
.map_err(|error| CallError::new(CallErrorKind::Internal, error.to_string()))?;
Ok(object)
})
}
@@ -607,7 +607,9 @@ pub enum CallErrorKind {
OperationNotFound,
/// Supplied named values do not satisfy the operation declaration.
InvalidArguments,
/// The encoded implementation result violates its declaration.
/// The Host constructed an invalid response before operation execution.
Internal,
/// The encoded implementation result violates its declaration after execution.
InvalidResult,
/// This operation requires a validator and the call omitted it.
ValidatorRequired,
@@ -683,7 +685,10 @@ impl CallError {
CallErrorKind::InterfaceMismatch => ProtocolErrorCode::InterfaceMismatch,
CallErrorKind::OperationNotFound => ProtocolErrorCode::OperationNotFound,
CallErrorKind::InvalidArguments => ProtocolErrorCode::InvalidArguments,
CallErrorKind::InvalidResult => ProtocolErrorCode::InvalidResult,
CallErrorKind::Internal => ProtocolErrorCode::Internal,
CallErrorKind::InvalidResult | CallErrorKind::Implementation => {
ProtocolErrorCode::OperationOutcomeUnknown
}
CallErrorKind::ValidatorRequired => ProtocolErrorCode::ValidatorRequired,
CallErrorKind::ValidatorMismatch => ProtocolErrorCode::ValidatorMismatch,
CallErrorKind::InterfaceValidatorRequired => {
@@ -693,7 +698,6 @@ impl CallError {
ProtocolErrorCode::InterfaceValidatorMismatch
}
CallErrorKind::PermissionDenied => ProtocolErrorCode::PermissionDenied,
CallErrorKind::Implementation => ProtocolErrorCode::Internal,
};
ProtocolError {
code,
+13 -3
View File
@@ -235,6 +235,10 @@ impl ObjectProvider for TestProvider {
)
}
"/empty" => (Document::open("empty", None, Rc::clone(&self.calls)), 0),
"/invalid-object" => (
Document::open("wrong-name", None, Rc::clone(&self.calls)),
0,
),
"/broken" => (
Document::open("broken", Some("broken-ref"), Rc::clone(&self.calls)),
3,
@@ -624,9 +628,15 @@ fn immutable_interface_rejects_a_supplied_validator() {
}
#[test]
fn invalid_results_and_backend_failures_keep_distinct_protocol_codes() {
fn invalid_host_responses_and_uncertain_operation_failures_use_canonical_codes() {
let (_, provider, _) = registry_and_provider();
assert_failure(
provider.fetch("/invalid-object").unwrap_err(),
CallErrorKind::Internal,
ProtocolErrorCode::Internal,
);
assert_failure(
provider
.call_operation(request(
@@ -639,7 +649,7 @@ fn invalid_results_and_backend_failures_keep_distinct_protocol_codes() {
))
.unwrap_err(),
CallErrorKind::InvalidResult,
ProtocolErrorCode::InvalidResult,
ProtocolErrorCode::OperationOutcomeUnknown,
);
assert_failure(
provider
@@ -653,6 +663,6 @@ fn invalid_results_and_backend_failures_keep_distinct_protocol_codes() {
))
.unwrap_err(),
CallErrorKind::Implementation,
ProtocolErrorCode::Internal,
ProtocolErrorCode::OperationOutcomeUnknown,
);
}