zerodds_rpc/error.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! Fehler-Typen fuer das DDS-RPC-Crate (C6.1.A).
5//!
6//! Wird von [`crate::common_types`], [`crate::topic_naming`],
7//! [`crate::annotations`] und [`crate::service_mapping`] geteilt.
8
9extern crate alloc;
10
11use alloc::string::{String, ToString};
12use core::fmt;
13
14/// Sammelfehler fuer die Foundation-Stufe der DDS-RPC-Implementierung.
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum RpcError {
17 /// XCDR2-Encoding/Decoding hat das Wire-Format verletzt.
18 Codec(String),
19 /// DoS-Cap fuer Wire-Payload ueberschritten.
20 PayloadTooLarge {
21 /// Beobachtete Bytes.
22 got: usize,
23 /// Erlaubtes Maximum.
24 max: usize,
25 },
26 /// Service-Name ist leer oder enthaelt ungueltige Zeichen.
27 InvalidServiceName(String),
28 /// Methoden-Name ist leer oder ungueltig.
29 InvalidMethodName(String),
30 /// Methode ist `oneway`, hat aber ein non-`void` Return.
31 OnewayWithReturn(String),
32 /// Methode ist `oneway`, hat aber `out`/`inout`-Parameter.
33 OnewayWithOutParam {
34 /// Methoden-Name.
35 method: String,
36 /// Parameter-Name.
37 param: String,
38 },
39 /// Doppelte Methoden-Namen in einem `interface`.
40 DuplicateMethod(String),
41 /// Doppelte Parameter-Namen in einer Methode.
42 DuplicateParam {
43 /// Methoden-Name.
44 method: String,
45 /// Parameter-Name.
46 param: String,
47 },
48 /// Unbekannter `RemoteExceptionCode_t`-Diskriminator beim Decode.
49 UnknownExceptionCode(u32),
50 /// Service ohne Methoden — kein Endpoint kann gebaut werden.
51 EmptyService(String),
52 /// Request-Reply-Wartezeit ueberschritten (Foundation-Stufe C6.1.C).
53 Timeout,
54 /// Server-Side hat eine `RemoteExceptionCode` ungleich `Ok` zurueckgegeben.
55 /// Der Wert ist der raw Diskriminator — Caller kann
56 /// [`crate::common_types::RemoteExceptionCode::from_u32`] nutzen, um in
57 /// das Enum zu mappen.
58 RemoteException(u32),
59 /// Doppelt vergebener `service_instance_name` auf demselben Participant.
60 DuplicateInstanceName(String),
61 /// Generischer DCPS-Aufruf-Fehler (Topic-Anlegen, Writer-Create etc.).
62 Dcps(String),
63 /// QoS-Profile nicht in der `DdsXml`-Library gefunden.
64 QosProfileNotFound(String),
65}
66
67impl fmt::Display for RpcError {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match self {
70 Self::Codec(s) => write!(f, "rpc codec error: {s}"),
71 Self::PayloadTooLarge { got, max } => {
72 write!(f, "rpc payload too large: {got} > {max}")
73 }
74 Self::InvalidServiceName(s) => write!(f, "invalid service name: {s:?}"),
75 Self::InvalidMethodName(s) => write!(f, "invalid method name: {s:?}"),
76 Self::OnewayWithReturn(m) => {
77 write!(f, "oneway method {m:?} must return void")
78 }
79 Self::OnewayWithOutParam { method, param } => write!(
80 f,
81 "oneway method {method:?} must not have out/inout param {param:?}"
82 ),
83 Self::DuplicateMethod(m) => write!(f, "duplicate method {m:?}"),
84 Self::DuplicateParam { method, param } => {
85 write!(f, "duplicate parameter {param:?} in method {method:?}")
86 }
87 Self::UnknownExceptionCode(v) => {
88 write!(f, "unknown RemoteExceptionCode_t discriminator {v}")
89 }
90 Self::EmptyService(n) => write!(f, "service {n:?} has no methods"),
91 Self::Timeout => write!(f, "rpc request timed out"),
92 Self::RemoteException(code) => {
93 write!(f, "remote exception code {code}")
94 }
95 Self::DuplicateInstanceName(n) => {
96 write!(f, "duplicate service instance name {n:?}")
97 }
98 Self::Dcps(s) => write!(f, "dcps error: {s}"),
99 Self::QosProfileNotFound(n) => {
100 write!(f, "qos profile {n:?} not found")
101 }
102 }
103 }
104}
105
106#[cfg(feature = "std")]
107impl std::error::Error for RpcError {}
108
109impl RpcError {
110 /// Convenience: Konstruktor fuer Codec-Fehler aus statischer Message.
111 #[must_use]
112 pub fn codec(msg: &str) -> Self {
113 Self::Codec(msg.to_string())
114 }
115}
116
117/// Result-Alias.
118pub type RpcResult<T> = core::result::Result<T, RpcError>;