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

chore(java): refactor error handling #2325

Merged
merged 13 commits into from May 21, 2024
Merged

Conversation

LuQQiu
Copy link
Collaborator

@LuQQiu LuQQiu commented May 11, 2024

Refactor the error handling to map errors (with an ErrorExt trait) following Lance Python convention

@LuQQiu LuQQiu requested a review from eddyxu May 11, 2024 04:04
@github-actions github-actions bot added the chore label May 11, 2024
IllegalArgumentException,
IOException,
RuntimeException,
pub type JavaResult<T> = std::result::Result<T, JavaError>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eddyxu @QianZhu PTAL, please mainly take a look this class.
The others are mainly moving classes around, and refactor it to use the new error handling approach

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LuQQiu can we add tests to capture those errors? Specifically, whether the clear error message is presented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually just name this as

type Result<T> = std::result::Result<T, Error>`


Struct Error {
...}

So, within this crate, it still reads in a style that is consistent with a Rust project.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to mimic the Python side, turn Result finally to a special end Result

}
#[derive(Debug)]
pub struct JavaError {
message: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as @wjones127 pointed out in #2316, to get more precise error info, it might be better to put a BoxedError here. like

#[derive(Debug)]
pub struct JavaError {
    source: BoxedError,
    java_class: JavaExceptionClass,
}

BoxedError is defined here:
BoxedError

I haven't read much of the Lance codebase, correct me if I'm wrong

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@broccoliSpicy Good to know about the BoxedError and its benefits! Thanks for the knowledge transfer!
For java side, this JavaError is a last mile error to the user, which translates the LanceError into Java Error with string message.
The information in the BoxedError will be included in this String message
e.g. In lance Error,
#[snafu(display("Dataset at path {path} was not found: {source}, {location}"))]
DatasetNotFound {
path: String,
source: BoxedError,
location: Location,
},
on java side we directly call LanceError.toString() to get the message with source information.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LuQQiu glad to know how error message is transfered from lance to jave, thanks!

@LuQQiu LuQQiu requested a review from QianZhu May 17, 2024 15:50
@LuQQiu
Copy link
Collaborator Author

LuQQiu commented May 18, 2024

@QianZhu PTAL, thanks!

@LuQQiu
Copy link
Collaborator Author

LuQQiu commented May 20, 2024

@QianZhu Added some test cases
while adding the test cases, found out some unsafe operations so

  1. Add the ReentrantReadWriteLock for dataset and scanner objects
  2. Avoid clone the Rust JNI object, following the safety requirement at https://docs.rs/jni/latest/jni/struct.JNIEnv.html#method.set_rust_field

fn infer_error(self) -> JavaResult<T>;
}

impl<T> JavaErrorExt<T> for std::result::Result<T, LanceError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is first time i saw the conversion on Result instead of Error. Why do we do this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mimic the Python side to reduce the error conversion headache, we do not need to list out all the errors and create the message for each error again, makes the error conversion much easier (keep the original info while can convert to target java exception)

#[snafu(display("Unknown error: {message}, {location}"))]
Other { message: String, location: Location },
#[derive(Debug)]
pub struct JavaError {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets just name this to Error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to mimic PyResult and PyErr lol
represent a special kind of end result/error

@LuQQiu LuQQiu merged commit 7acac5f into lancedb:main May 21, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants