Skip to content

Instantly share code, notes, and snippets.

@rfk
Created May 25, 2021 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rfk/71297d62ac851d2496eb0bb41a8a6f8f to your computer and use it in GitHub Desktop.
Save rfk/71297d62ac851d2496eb0bb41a8a6f8f to your computer and use it in GitHub Desktop.
// Have one error class that exposed by UniFFI, defined in your `.udl` file
// and with a correspondong struct definition in `lib.rs`. It's flat, because
// UniFFI doesn't pass nice nested structure in errors (yet).
//
// Instances of this error will only ever appear on the boundary of your API,
// where they get handed off to the foreign-language code.
//
pub enum LoginsError {
UnexpectedLoginsStorageError(String),
SyncAuthInvalid(String),
MismatchedLock(&'static str),
// A separate case for each invalid login reason.
InvalidRecordEmptyOrigin(String),
InvalidRecordEmptyPassword(String),
// ...etc...
}
// Have a separate Error class for internal use with nice rich structure.
// Doesn't actually have to be called "internal" :-)
//
pub enum InternalLoginsError {
UnexpectedLoginsStorageError(String),
SyncAuthInvalid(String),
MismatchedLock(&'static str),
// InvalidLoginReason can be a nested structure here,
// since that's nicer to work with in the Rust code.
InvalidRecord(String, InvalidLoginReason),
}
// Make a `From` impl to convert the rich internal errors to pass over the FFI.
//
impl From<InternalLoginsError> for LoginsError {
fn from(e: LoginsStorageError) -> Self {
// The logic here matches the `get_code` logic from the hand-written bindings,
// recursing into the `InvalidRecord()` options and flattening them out.
}
}
// Any public API functions should throw a `LoginsError`.
// I'm pretty sure that the `?` operator will automatically find and use the `From` impl
// to do the conversion.
// On the Kotlin side, you may like to do the reverse of your `From` impl,
// and map the flat list of errors back into a richer structured error.
// That would have to be all in hand-written Kotlin code for now though.
@rfk
Copy link
Author

rfk commented May 25, 2021

The .udl for the error would then need to look like:

[Error]
enum LoginsError {
          "UnexpectedLoginsStorageError",
          "SyncAuthInvalid",
          "MismatchedLock",
          "InvalidRecordEmptyOrigin"
          "InvalidRecordEmptyPassword",
          // ..etc...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment