3

I have a python code block in an org-file that when executed results in some error. I was expecting to see that error in the #+RESULTS: block, but it doesn't show up. I have to navigate to the python session buffer in order to see whether the evaluation was successful. More over, when a previous code block is unsuccessful, and the next code block depends on it's results, I can continue executing code without any indications that evaluation is failing (except for missing output).

How can I configure org-babel to display such errors/exceptions in the #+RESULTS: block?

How to reproduce

I have this property set at the top of my org file

#+PROPERTY: header-args :session my_py_session

Sample block

#+BEGIN_SRC python
r = some_function_which_results_in_a_trace_back()
#+END_SRC

#+BEGIN_SRC python
x = r*2
#+END_SRC

When I do a C-c on both these blocks, Emacs reports something like Code block evaluation complete (took 0.5 secs) in the mini buffer.

But when I open the python session buffer, I see this error. How can I get this error to show in the #+RESULTS: block?

>>> 
org_babel_python_eoe
Traceback (most recent call last):
  File "<string>", line 17, in __PYTHON_EL_eval
  File "/var/folders/7k/r1g1zhmx16gbtm1hbllhhk_w0000gs/T/py3Fvne8", line 18, in <module>
  File "<string>", line 4, in <module>
  File "<string>", line 2, in <module>
NameError: name 'some_function_which_results_in_a_trace_back' is not defined. Did you mean: 'NameError'?
>>> 
org_babel_python_eoe
Traceback (most recent call last):
  File "<string>", line 17, in __PYTHON_EL_eval
  File "/var/folders/7k/r1g1zhmx16gbtm1hbllhhk_w0000gs/T/pywWfEwY", line 8, in <module>
  File "<string>", line 1, in <module>
NameError: name 'r' is not defined

What I already tried

#+BEGIN_SRC python :results output
try:
    r = some_error()
except Exception as e:
    print(e)
#+END_SRC

#+RESULTS:
: name 'some_error' is not defined
1

1 Answer 1

1

Do you want the whole stacktrace? Or are you fine with just the error message?

Override this function to your heart's content:

(advice-add #'org-babel-python-send-string 
            :override
            #'my/org-babel-python-send-string)

(defun my/org-babel-python-send-string (session body)
  "Pass BODY to the Python process in SESSION.
Return output."
  (with-current-buffer session
    (let* ((string-buffer "")
       (comint-output-filter-functions
        (cons (lambda (text) (setq string-buffer
                       (concat string-buffer text)))
          comint-output-filter-functions))
       (body (format "\
try:
%s
except Exception as e:
    # These are the relevant lines to change. 
    print(e)
finally:
    print('%s')"
             (org-babel-python--shift-right body 4)
             org-babel-python-eoe-indicator)))
      (let ((python-shell-buffer-name
         (org-babel-python-without-earmuffs session)))
    (python-shell-send-string body))
      ;; same as `python-shell-comint-end-of-output-p' in emacs-25.1+
      (while (not (and (python-shell-comint-end-of-output-p string-buffer)
                       (string-match
                org-babel-python-eoe-indicator
                string-buffer)))
    (accept-process-output (get-buffer-process (current-buffer))))
      (org-babel-chomp (substring string-buffer 0 (match-beginning 0))))))

You'll also need to change:

#+PROPERTY: header-args :session my_py_session

to

#+PROPERTY: header-args :session my_py_session :results output

Insert the appropriate python code if you want the whole stacktrace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.