GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [Bug]: Re-raise through try/except drops the exec'd code's frame from the polyglot stack trace · Issue #1295 · oracle/graalpython

[Bug]: Re-raise through try/except drops the exec'd code's frame from the polyglot stack trace #1295

New issue
Copy link
New issue
Copy link
Open
Open
[Bug]: Re-raise through try/except drops the exec'd code's frame from the polyglot stack trace#1295
Copy link

Description

@BigMichi1
BigMichi1
opened on Nov 9, 2026
Issue body actions

Follow-up to #1186 (fixed in 2247966).

Summary

With GraalPy 25.5.5.0.3, a Python exception re-raised through try/except … raise reaches the host with its error intact (the -ea crash IllegalArgumentException: Bytecode index out of range of #1186 is gone), but the polyglot stack trace still lacks the guest frame of the code that raised it. When the raising code runs through exec, its <module> frame (and so the line number the host needs) is missing; without the try/except … raise it is present.

Reproducer

https://github.com/BigMichi1/graalpy-reraise-stacktrace, StackTraceRepro (run with ./gradlew and -Pgraalpy=<release>):

String support = String.join("\n",
        "def with_except(code):",
        "    try:",
        "        exec(code, {})",
        "    except BaseException:",
        "        raise",
        "def plain(code):",
        "    exec(code, {})");
try (Context context = Context.create("python")) {
    context.eval(Source.newBuilder("python", support, "support.py").build());
    for (String fn : new String[] {"plain", "with_except"}) {
        try {
            context.getBindings("python").getMember(fn).execute("x = 1\nundefined_name");
        } catch (PolyglotException e) {
            System.out.println(fn + ":");
            for (PolyglotException.StackFrame f : e.getPolyglotStackTrace()) {
                if (f.isGuestFrame()) System.out.println("   " + f);
            }
        }
    }
}

Actual (25.5.5.0.3, with and without -ea, JDK 25.0.5)

plain:
   <python> <module>(<string>:2:6-19)
   <python> plain(support.py:7:116-129)
with_except:
   <python> with_except(support.py:2-5:27-93)

Expected

The with_except trace holds the frame that raised, as plain does:

with_except:
   <python> <module>(<string>:2:6-19)
   <python> with_except(support.py:...)

Before the fix of #1186 (25.4.4.1.1)

The same reproducer printed with_except(Unknown) without -ea, and with -ea the re-raise failed with Bytecode index out of range 168. So 25.5.5 fixed the crash and gave the handler frame a location; the frame of the exec'd code is still dropped.

Why it matters

An embedding (a JSR-223 engine running user scripts through exec) reports a failing script's line number from the polyglot stack trace. Any try/except … raise between the script and the host hides it, so the embedding still needs a workaround that keeps exception handling out of the frame that runs the script.

Activity

  1. msimacek commented on Nov 9, 2026

    @msimacek
    msimacek
    on Nov 9, 2026
    Contributor
    More actions

    Hi @BigMichi1. The problem stems from a mismatch between how Truffle and Python represent tracebacks. It cannot be fixed purely on GraalPy's side, it would need a rework of the stacktrace representation in Truffle. We've tried a few times to come up with some new design, but we've never found anything that would work without breaking Truffle's compatibility with other existing language implementations. It's still on our todo list.

    The traceback is correct from within python, so you can get the info from it by going through python. If you just want to format the python exception, you can use the traceback module like this:

    try {
        // ...
    } catch (PolyglotException e) {
        Value formatException = context.eval("python", """
                def _format_exception(e):
                    import traceback
                    return ''.join(traceback.format_exception(e))
                _format_exception
                """);
        System.out.print(formatException.execute(e.getGuestObject()).asString());
    }
  2. BigMichi1 commented on Nov 10, 2026

    @BigMichi1
    BigMichi1
    on Nov 10, 2026
    Author
    More actions

    Thank you for the explanation and the snippet, @msimacek. That makes sense; we won't wait for a Truffle-level change.

    We'll take your suggestion: our script engine will build the error text from the Python side with traceback.format_exception on the guest exception, so the script's frame and line come from the (correct) Python traceback. That also lets us drop the workaround we carried for this (running the script without the surrounding try/except). Feel free to keep the issue open for the Truffle redesign or close it, whichever suits your tracking.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.