Issue2650

classification
Title: Detail message is not set on PyException from PythonInterpreter
Type: behaviour Severity: normal
Components: Core Versions: Jython 2.7
Milestone: Jython 2.7.2
process
Status: pending Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: jamesmudd, jeff.allen
Priority: normal Keywords:

Created on 2017-12-08.13:18:18 by jamesmudd, last changed 2018-01-03.23:31:46 by jeff.allen.

Files
File name Uploaded Description Edit Remove
Main.java jamesmudd, 2017-12-08.13:18:17
Messages
msg11690 (view) Author: James Mudd (jamesmudd) Date: 2017-12-08.13:18:17
When a PyException is created the detailMessage field of the Java exception is not filled in. This is probamatic when you use a Java logging framework and a PyException is caught. The detailMessage is used to build the logging output by calling e.getMessage() on the exception.

See the attached Main.java code which illiterates the issue. The output is:
    Exception happened in script: null
    Exception happened in script: NameError: name 's' is not defined in <script> at line number 1

It also shows how this is handled differently if using the python script engine. There the message is filled by calling Py.formatException(type, value) when the ScriptException is constructed.

I propose this could be added to the PyException constructor to initialise the detailMessage, I will create a pull request to do that.

In general though I think it might be better to refactor PyException to be immutable, which make sense for an Exception as it should capture the state when its thrown and can't be modified after that. I will look into that as a separate pull request.
msg11691 (view) Author: James Mudd (jamesmudd) Date: 2017-12-18.08:51:53
I have a pull request to fix this https://github.com/jythontools/jython/pull/97

The detail message is initialised in the same way it would be generated when throwing ScriptException i.e using Py.formatException(type, value)
msg11693 (view) Author: Jeff Allen (jeff.allen) Date: 2018-01-02.19:26:42
I think this approach to exceptions, deferring the creation of a message, is deliberate, to make PyException lightweight.

The use case is good, however. The exception ought not to escape without a message. More thiughts on the GitHub companion PR at https://github.com/jythontools/jython/pull/97 .
msg11695 (view) Author: James Mudd (jamesmudd) Date: 2018-01-03.18:25:01
I have just updated the PR with the suggestions. This now only builds the message when its requested.

The output of the test program is now:
    Exception happened in script: NameError: name 's' is not defined
    Exception happened in script: NameError: name 's' is not defined in <script> at line number 1

While it doesn't get the nice script and line number of the ScriptException I think this is correct because these are additional features of ScriptException.
msg11696 (view) Author: Jeff Allen (jeff.allen) Date: 2018-01-03.23:31:45
From a similar program to the one James posts, we now receive:

PythonInterpreter said: NameError: name 's' is not defined
And the stacktrace is:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 's' is not defined

ScriptEngine said:      NameError: name 's' is not defined in <script> at line number 1
And the stacktrace is:
javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 1
        at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:222)
        at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:59)
        at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
        at issues.Issue2650.main(Issue2650.java:29)
Caused by: Traceback (most recent call last):
  File "<script>", line 1, in <module>
NameError: name 's' is not defined

        at org.python.core.Py.NameError(Py.java:268)
        at org.python.core.PyFrame.getname(PyFrame.java:257)
        at org.python.pycode._pyx1.f$0(<script>:1)
        at org.python.pycode._pyx1.call_function(<script>)
        at org.python.core.PyTableCode.call(PyTableCode.java:171)
        at org.python.core.PyCode.call(PyCode.java:18)
        at org.python.core.Py.runCode(Py.java:1589)
        at org.python.core.__builtin__.eval(__builtin__.java:497)
        at org.python.core.__builtin__.eval(__builtin__.java:501)
        at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259)
        at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57)
        ... 3 more

Interesting differences, but all the Python information is in both and the critical shortcoming is fixed.

Now committed at: https://hg.python.org/jython/rev/d74f8c2cd56f
History
Date User Action Args
2018-01-03 23:31:46jeff.allensetpriority: normal
status: open -> pending
resolution: fixed
messages: + msg11696
title: detailMessage is not set on PyException -> Detail message is not set on PyException from PythonInterpreter
2018-01-03 18:25:02jamesmuddsetmessages: + msg11695
2018-01-02 19:26:43jeff.allensetnosy: + jeff.allen
messages: + msg11693
2017-12-18 08:51:54jamesmuddsetmessages: + msg11691
2017-12-08 13:18:18jamesmuddcreate