flutter_rust_bridge icon indicating copy to clipboard operation
flutter_rust_bridge copied to clipboard

Rust Error enums unable to determine the specific type in dart code

Open ipconfiger opened this issue 7 months ago • 3 comments

If i define a Error enum, and throw it

pub enum IMError{
    SerdeErr(serde_json::Error),
    HttpErr(HttpError),
    LogicErr(String)
}


#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
pub fn test_it(name: String) -> Result<String, IMError> {
    //Ok(format!("Hello, {name}!"))
    Err(IMError::LogicErr(format!("test error:{name}")))
}

it will generate a Dart class

@sealed
class ImErrorImpl extends RustOpaque implements ImError {
  // Not to be used by end users
  ImErrorImpl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  ImErrorImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_ImError,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_ImError,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_ImErrorPtr,
  );
}

it can be catch in a try catch block

But pls tell me how to determine witch Error it is?

ipconfiger avatar May 17 '25 15:05 ipconfiger

Maybe make IMError non_opaque, e.g. I expect serde_json::Error causes it to be opaque

fzyzcjy avatar May 18 '25 13:05 fzyzcjy

@fzyzcjy Yes, you are right, it caused by serde_json::Error and HttpError. i write a customer error struct instead of serde_json::Error and HttpError, then use From trait to translate serde_json::Error and HttpError to my customer struct. It works.


#[derive(Debug, Serialize)]
pub struct JsonError {
    pub info: String
}

#[derive(Debug, Serialize)]
pub struct WebError {
    pub info: String
}


#[warn(dead_code)]
pub enum IMError{
    SerdeErr(JsonError), 
    HttpErr(WebError),
    LogicErr(String)
}

impl From<serde_json::Error> for IMError {
    fn from(value: serde_json::Error) -> Self {
        println!("Raise a Serde error:{value:?}");
        Self::SerdeErr(JsonError { info: format!("{value:?}") })
    }
}

impl From<HttpError> for IMError {
    fn from(value: HttpError) -> Self {
        println!("Raise a Http error:{value:?}");
        Self::HttpErr(WebError { info: format!("{value:?}") })
    }
}

impl From<String> for IMError {
    fn from(value: String) -> Self {
        println!("Raise a logic error:{value}");
        Self::LogicErr(value)
    }
}

when i throw a error,i got:

IMError.logicErr(field0: test error)
package:flutter_rust_bridge/src/codec/base.dart 32:9                SimpleDecoder.decode
package:flutter_rust_bridge/src/codec/sse.dart 45:55                SseCodec._decode
package:flutter_rust_bridge/src/codec/sse.dart 40:7                 SseCodec.decodeWireSyncType
package:flutter_rust_bridge/src/main_components/handler.dart 34:25  BaseHandler.executeSync
package:im_client/src/rust/frb_generated.dart 518:20                RustLibApiImpl.crateApiImClientTestIt
package:im_client/src/rust/api/im_client.dart 16:26                 testIt
test/im_client_test.dart 19:24             

ipconfiger avatar May 21 '25 07:05 ipconfiger

Looks good! So looks like it is expected behavior (it throws)?

fzyzcjy avatar May 21 '25 15:05 fzyzcjy

Close since this seems to be solved, but feel free to reopen if there are any questions!

fzyzcjy avatar Jul 01 '25 14:07 fzyzcjy

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.

github-actions[bot] avatar Jul 15 '25 15:07 github-actions[bot]