leekeiabstraction commented on code in PR #302:
URL: https://github.com/apache/fluss-rust/pull/302#discussion_r2799300765


##########
bindings/cpp/include/fluss.hpp:
##########
@@ -46,6 +46,134 @@ struct UpsertWriter;
 struct Lookuper;
 }  // namespace ffi
 
+/// Named constants for Fluss API error codes.
+///
+/// Server API errors have error_code > 0 or == -1.
+/// Client-side errors have error_code == CLIENT_ERROR (-2).
+/// These constants match the Rust core FlussError enum and are stable across 
protocol versions.
+/// New server error codes work automatically (error_code is a raw int, not a 
closed enum) —
+/// these constants are convenience names, not an exhaustive list.
+struct ErrorCode {
+    /// Client-side error (not from server API protocol). Check error_message 
for details.
+    static constexpr int CLIENT_ERROR = -2;
+    /// The server experienced an unexpected error when processing the request.
+    static constexpr int UNKNOWN_SERVER_ERROR = -1;
+    /// The server disconnected before a response was received.
+    static constexpr int NETWORK_EXCEPTION = 1;

Review Comment:
   Curious on why we don't have none (0) here?



##########
bindings/python/src/error.rs:
##########
@@ -18,28 +18,246 @@
 use pyo3::exceptions::PyException;
 use pyo3::prelude::*;
 
+/// Error code for client-side errors that did not originate from the server 
API protocol.
+/// The value -2 is outside the server API error code range (-1 .. 57+), so it 
will never
+/// collide with current or future API codes. Consistent with the CPP binding.
+const CLIENT_ERROR_CODE: i32 = -2;
+
 /// Fluss errors
 #[pyclass(extends=PyException)]
 #[derive(Debug, Clone)]
 pub struct FlussError {
     #[pyo3(get)]
     pub message: String,
+    #[pyo3(get)]
+    pub error_code: i32,
 }
 
 #[pymethods]
 impl FlussError {
     #[new]
-    fn new(message: String) -> Self {
-        Self { message }
+    #[pyo3(signature = (message, error_code=-2))]
+    fn new(message: String, error_code: i32) -> Self {
+        Self {
+            message,
+            error_code,
+        }
     }
 
     fn __str__(&self) -> String {
-        format!("FlussError: {}", self.message)
+        if self.error_code != CLIENT_ERROR_CODE {
+            format!("FlussError(code={}): {}", self.error_code, self.message)
+        } else {
+            format!("FlussError: {}", self.message)
+        }
     }
 }
 
 impl FlussError {
     pub fn new_err(message: impl ToString) -> PyErr {
-        PyErr::new::<FlussError, _>(message.to_string())
+        PyErr::new::<FlussError, _>((message.to_string(), CLIENT_ERROR_CODE))
+    }
+
+    /// Create a PyErr from a core Error.
+    /// `FlussAPIError` variants carry the server protocol error code directly.
+    /// All other error kinds are client-side and use CLIENT_ERROR_CODE.
+    pub fn from_core_error(error: &fluss::error::Error) -> PyErr {
+        use fluss::error::Error;
+        let (msg, code) = match error {
+            Error::FlussAPIError { api_error } => (api_error.message.clone(), 
api_error.code),
+            _ => (error.to_string(), CLIENT_ERROR_CODE),
+        };
+        PyErr::new::<FlussError, _>((msg, code))
     }
 }
+
+/// Named constants for Fluss API error codes.
+///
+/// Server API errors have error_code > 0 or == -1.
+/// Client-side errors have error_code == CLIENT_ERROR (-2).
+/// These constants match the Rust core FlussError enum and are stable across 
protocol versions.
+/// New server error codes work automatically (error_code is a raw int, not a 
closed enum) —
+/// these constants are convenience names, not an exhaustive list.
+#[pyclass]
+pub struct ErrorCode;
+
+#[pymethods]
+impl ErrorCode {
+    /// Client-side error (not from server API protocol). Check the error 
message for details.
+    #[classattr]
+    const CLIENT_ERROR: i32 = -2;
+    /// The server experienced an unexpected error when processing the request.
+    #[classattr]
+    const UNKNOWN_SERVER_ERROR: i32 = -1;
+    /// The server disconnected before a response was received.
+    #[classattr]
+    const NETWORK_EXCEPTION: i32 = 1;

Review Comment:
   Similarly here as well



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to