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

Exceptions and Errors should be percolated to the application on both java and python side #253

Closed
243826 opened this issue Aug 19, 2016 · 7 comments

Comments

@243826
Copy link
Contributor

243826 commented Aug 19, 2016

See below.

It's a must that application should know of the precise faults happening at the infrastructure level that are not handled at all. Errors are of greater interest as they pose potential security risks.

In the following case I would like both Java side and python side to exit upon applications mandate (not the default library behavior) but the issue is that the fault happens in a thread within py4j library and it's not percolated.

The eventual result that we see is we lose some data. It's a postmortem of lost data which led me to this code.

A way to implement such a notification is to let the application register a handler and provide sufficient information in the callback to relate the fault with the request/proxy. I also see that the socket leaks out whenever there is an exception.

Exception in thread "Thread-9" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2367)
        at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
        at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:535)
        at java.lang.StringBuffer.append(StringBuffer.java:322)
        at java.io.BufferedReader.readLine(BufferedReader.java:363)
        at java.io.BufferedReader.readLine(BufferedReader.java:382)
        at py4j.commands.AbstractCommand.getStringArguments(AbstractCommand.java:102)
        at py4j.commands.AbstractCommand.getArguments(AbstractCommand.java:78)
        at py4j.commands.CallCommand.execute(CallCommand.java:77)
        at py4j.GatewayConnection.run(GatewayConnection.java:209)
        at java.lang.Thread.run(Thread.java:745)
ERROR:py4j.java_gateway:Error while sending or receiving.
Traceback (most recent call last):
  File "/home/xxx/master/candid/runenv/lib64/python2.7/site-packages/py4j/java_gateway.py", line 768, in send_command
    raise Py4JError("Answer from Java side is empty")
Py4JError: Answer from Java side is empty
@bartdag
Copy link
Collaborator

bartdag commented Aug 20, 2016

Ok, so if I understand correctly, and out of memory error occurred on the Java side.

The python side received the error and raised an exception with the Java exception trace. Does the behavior of the python side work with your use case?

The Java side on the other hand did not raise any exception that you could catch and you would like a way to know when something bad happen.

If I look at this particular use case, I see that Py4J logs the error, but the log level could definitively be higher:

logger.log(Level.FINE, "Received exception while executing this command: " + methodName, e);

I guess I could add a method to the GatewayServerListener, something like commandError(Exception e), but it's tricky because if the listeners take a long time or block, the Python side won't get the error.

I'm trying to find examples of inversion of control frameworks that provide exception callbacks in addition to logging, if you have any example, that would help.

@243826
Copy link
Contributor Author

243826 commented Aug 20, 2016

I don't think we (library) should log the error at all. We should forward
it to the application which can decide if it wants to log it/handle it/or
terminate itself.

I am on the phone, will think and respond for IoC. Thanks.

On Aug 19, 2016 5:22 PM, "Barthelemy Dagenais" notifications@github.com
wrote:

Ok, so if I understand correctly, and out of memory error occurred on the
Java side.

The python side received the error and raised an exception with the Java
exception trace. Does the behavior of the python side work with your use
case?

The Java side on the other hand did not raise any exception that you could
catch and you would like a way to know when something bad happen.

If I look at this particular use case, I see that Py4J logs the error, but
the log level could definitively be higher:

logger.log(Level.FINE, "Received exception while executing this command: "

  • methodName, e);

I guess I could add a method to the GatewayServerListener, something like
commandError(Exception e), but it's tricky because if the listeners take a
long time or block, the Python side won't get the error.

I'm trying to find examples of inversion of control frameworks that
provide exception callbacks in addition to logging, if you have any
example, that would help.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#253 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACk9wwxhT5v3k4_JxQ1ybpOb8Afjn5xnks5qhkilgaJpZM4Jo6Ss
.

@bartdag
Copy link
Collaborator

bartdag commented Aug 20, 2016

Hi!

regarding the current logging behavior, I'm positive this is the right way to do it. By using standard logging tool, I leave the user in complete control over what to do with the log (e.g., write to file, ignore, only report most important errors, etc.)

Regarding exception handlers with IoC, I found a few examples that offer various callbacks, but it's usually buried deep in the documentation. I think the current GatewayServerListener would be a good entry point for that.

I'm currently working on a new transport strategy and changing most of Py4J's protocol so I'll keep that in mind when working with GatewayConnection and CallbackConnection.

@scottslewis
Copy link

Hi Barthelemy and 243826.

We've been successfully using Py4j for some time (for java <-> python osgi remote services) and would like to get an enhancement: When calling from Java -> Python, if a Python error occurs during the execution of the target method, this error (and it's stack trace) does not propogate back to Java. Rather it's simply logged and then the method returns null on Java side (I believe). We would prefer it if the java method threw sometime of runtime exception with (possibly) the python stack trace in the Java's StackTraceElements filled to contain the python stack elements/Strings. Does this bug incorporate this case? Or should I open another bug/enhancement request specifically for this? I believe it will probably require some enhancement to the protocol to support, unless it's there and I haven't seen it. thanks.

@243826
Copy link
Contributor Author

243826 commented Nov 20, 2017

I think this bug is asking for the same. I defer to Barthelemy for the final word. Thanks.

@bartdag
Copy link
Collaborator

bartdag commented Nov 23, 2017

Hi all, someone made a pull request that will likely found its way in the next Py4J release: #294

Would this solution works for you?

@bartdag
Copy link
Collaborator

bartdag commented Jan 5, 2018

Please reopen if needed (issue addressed by #294)

@bartdag bartdag closed this as completed Jan 5, 2018
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