5.1 KiB
Task 11: Fix Exception Display in Org Buffer
Problem
When an Elixir code block throws an exception, the error is not displayed in the org buffer. The error is only shown in the minibuffer/messages, leaving the user without visible feedback in their document.
Root Cause
- The variable
ob-elixir-signal-errorsdefaults tot(line 57-63 inob-elixir.el) - When an error is detected,
ob-elixir--process-result(line 206-222) callssignal, which throws an Emacs error - The signaled error propagates up and prevents
org-babel-execute:elixirfrom returning a result - Since no result is returned, org-babel has nothing to insert into the buffer
Current Behavior
ob-elixir-signal-errors |
What happens |
|---|---|
t (default) |
Error is signaled, shown in minibuffer, NOT inserted in buffer |
nil |
Error is returned as the result string, inserted in buffer |
Desired Behavior
Errors should always be displayed in the org buffer as the result, regardless of the ob-elixir-signal-errors setting.
Scope
- Non-session execution mode only
- Session mode is out of scope for this fix
Implementation Plan
Step 1: Modify ob-elixir--process-result to pass full error output
File: ob-elixir.el (line 218)
Change: When signaling an error, pass the full error output instead of the formatted short message.
Current code (line 218):
(list (ob-elixir--format-error error-info)))
Proposed change:
(list (plist-get error-info :full-output)))
Rationale:
- The
:full-outputfield contains the complete multi-line error output including stack traces - This ensures the
condition-caseinorg-babel-execute:elixirreturns the same full output that would be returned whenob-elixir-signal-errorsisnil - The formatted short message from
ob-elixir--format-erroronly includes the exception name and first-line message, which is insufficient for debugging
Step 2: Wrap result computation in org-babel-execute:elixir (ALREADY DONE)
File: ob-elixir.el (lines 928-945)
Status: This step was already implemented. The condition-case wraps the result computation and catches ob-elixir-error, returning (cadr err) which will now contain the full error output after Step 1 is applied.
(result (condition-case err
(cond
;; Session mode with deps
((and session (not (string= session "none")) deps-string)
(ob-elixir--evaluate-in-session-with-deps
session full-body result-type deps-string))
;; Session mode without deps
((and session (not (string= session "none")))
(ob-elixir--evaluate-in-session session full-body result-type))
;; Non-session with deps
(deps-string
(ob-elixir--execute-with-deps full-body result-type deps-string))
;; Plain execution
(t
(ob-elixir--execute full-body result-type)))
(ob-elixir-error
;; Return error message so it appears in buffer
(cadr err))))
Step 3: Add tests for the new behavior
File: test/test-ob-elixir-errors.el
Add new test: Verify that errors appear in org buffer output when ob-elixir-signal-errors is t.
(ert-deftest ob-elixir-test-error-appears-in-result ()
"Test that errors appear in result even when signaling is enabled."
(skip-unless (executable-find ob-elixir-command))
(let ((ob-elixir-signal-errors t))
;; Execute via the main entry point (not ob-elixir--execute directly)
(let ((result (org-babel-execute:elixir "raise \"test error\""
'((:result-type . value)
(:result-params . ("replace"))))))
;; Result should contain the error, not be nil/empty
(should result)
(should (string-match-p "RuntimeError" result)))))
Rationale: The existing test ob-elixir-test-error-signaling tests that ob-elixir--execute signals an error, but doesn't test the full flow through org-babel-execute:elixir. The new test verifies the end-to-end behavior.
Step 4: Update TODO.org
File: TODO.org
Change: Mark the first item ("errors should be printed in the org buffer") as DONE.
Summary of Changes
| File | Change |
|---|---|
ob-elixir.el |
Change signal data to pass :full-output instead of formatted message |
ob-elixir.el |
Wrap result computation in condition-case to catch ob-elixir-error (already done) |
test/test-ob-elixir-errors.el |
Add test for error display in org buffer |
TODO.org |
Mark issue as resolved |
Files NOT Modified
- Session-related code
ob-elixir--process-result(keeps existing signaling behavior)ob-elixir-signal-errorsdefault value (stayst)
Verification
After implementation, test with:
#+begin_src elixir
raise "This error should appear in the buffer"
#+end_src
Expected: The RuntimeError message should appear as the result block below the code block.