Automating Java Exception Handling with EXCODER
EXCODER uses static and dynamic analysis to guide LLMs in generating Java exception-handling code.
EXCODER formalizes Java exception handling by treating code generation as a test-driven task. It automates the insertion of try/catch blocks and throw statements by grounding LLM outputs in specific runtime data. This approach replaces standard zero-shot prompting with a structured feedback loop derived from existing codebase analysis.
The Mechanism of Guided Generation
The framework extracts input for the LLM by combining static and dynamic program analysis to build a specialized context prompt. The static component parses the target method's abstract syntax tree to identify scope and control flow, while the dynamic component executes the provided Exceptional Behavior Tests (EBTs). By monitoring the program during these tests, the tool captures specific stack traces and the values of local variables at the moment of failure.
This data is formatted into a prompt that includes the target method snippet, the identified failure location, and the expected exception type. By injecting these concrete runtime observations—rather than asking the model to infer failure modes from code alone—the system constrains the generation space. For example, consider a method attempting to open a file that does not exist. A baseline LLM might generate a generic catch block that logs the error but fails to satisfy the specific EBT assertion. EXCODER, having captured the exact FileNotFoundException and the state of the File object from the EBT runtime execution, forces the model to synthesize a block that precisely matches the requirements needed to pass that test assertion.
Performance and Reliability
The improvement in reliability is measured by comparing the pass rate of generated code against a suite of tests. The baseline LLM prompt achieves a 73.36% pass rate, while the EXCODER-augmented approach reaches 85.92% on the same evaluation set. The gap between these figures highlights the difference between open-ended generation and generation constrained by observed execution data.
What remains unknown is the tool's performance in environments where EBT coverage is poor or the test suite itself is brittle. Since the model relies on the provided tests to ground its generation, the output is only as robust as the test suite provided to the framework. If the EBTs capture a narrow slice of potential failure states, the generated exception handling may fail when the program encounters unforeseen conditions not represented in the original test set. The utility of this approach for larger, highly interdependent codebases hinges on whether the static and dynamic analysis can maintain precision when the state space grows beyond what a single test run can effectively instrument.