Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to throw exceptions from rust #76

Closed
onelson opened this issue Feb 5, 2018 · 5 comments
Closed

How to throw exceptions from rust #76

onelson opened this issue Feb 5, 2018 · 5 comments

Comments

@onelson
Copy link

onelson commented Feb 5, 2018

I'm working on a rust crate with some functions that return Result - I'm hoping use the Err values to generate exceptions for the Java caller, but I'm not confident I'm using the provided API in the intended way.

The reason I'm doubtful is I expected to be able to do something like this:

#[no_mangle]                                                                   
#[allow(non_snake_case)]                                                       
pub extern "system" fn Java_MyLib_getMaybeBool(                               
    env: JNIEnv,                                                               
    class: JClass,                                                             
    input: JString,                                                            
) -> jboolean {                                                                
    let input: String = env.get_string(input)                                  
        .expect("Couldn't get java string!")                                   
        .into();                                                               

    match get_maybe_bool(&input) {
        Ok(output) => output as u8, 
        Err(err) => {                                                          
            env.throw(err.to_string()).unwrap();
            unreachable!();
        }                                                                      
    }                                                                          
} 

When I write this, the java caller segfaults in the Err case, hitting the unreachable!(); and then panics.

Instead, I'm returning a 0u8 following the throw, which I guess could be correct from a certain point of view (but not really). With the 0u8 return value, I see the caller get the exception and everything works how I'd think it should.

Am I missing some aspect of this? An example of throwing exceptions would be nice to have.

@jrobsonchase
Copy link
Contributor

jrobsonchase commented Feb 6, 2018 via email

@onelson
Copy link
Author

onelson commented Feb 6, 2018

OK, that makes some good sense.

I suppose I could aim to document this with a const BOOL_NOPE: u8 = 255; and just return BOOL_NOPE in these situations.

I was just wondering if there was some way to model the throwing of the exception in the function signature (like you might with a Result).

@dmitry-timofeev
Copy link
Contributor

That's a good question because this thing is tricky to handle properly. We ended up with the following (@DarkEld3r, please correct me if I'm wrong):

  • If a native function panics -- throw a Java runtime exception.
  • If a native function returns Err:
    • check if there is a pending (= already thrown) Java exception, do nothing if that's the case.
    • otherwise -- throw a proper Java exception to let the caller know about the error.
  • If a native function returns Ok: return to the Java side.

I can't say if this library can help with handling panics and errors, or simplify it.

@jrobsonchase
Copy link
Contributor

jrobsonchase commented Feb 6, 2018

There's nothing in this lib as of right now that can help with that, but it could be possible with the help of some macro magic.

Some time ago, I played around with wrapping the wren in Rust and came up with a macro system for doing some extra automatic translation of wren types -> rust types and adding safety wrappers. Example here.

Something similar could conceivably be included here if someone had the motivation to build it 😉

Edit: on second look, it doesn't appear that I ever got around to wrapping everything in a panic catch in my wren crate, but it wouldn't be hard to add.

@jrobsonchase
Copy link
Contributor

I think the question here has effectively been answered, and I filed an enhancement issue for some of the ergonomics improvements proposed here, so I'm closing this one.

Feel free to discuss more ergonomics improvements in #80!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants