Repository: hylang/hy

Issue:
Exception in __repr__ crashes repl
```Python
=> (defclass BadRepr[] (defn __repr__ [self] (/ 0)))
class BadRepr:

    def __repr__(self):
        return (1 / 0)
None
=> (BadRepr)
BadRepr()
Traceback (most recent call last):
  File "C:\Users\ME\workspace\hy36-gilch\Scripts\hy-script.py", line 11, in <module>
    load_entry_point('hy', 'console_scripts', 'hy')()
  File "c:\users\me\documents\github\hy\hy\cmdline.py", line 341, in hy_main
    sys.exit(cmdline_handler("hy", sys.argv))
  File "c:\users\me\documents\github\hy\hy\cmdline.py", line 336, in cmdline_handler
    return run_repl(spy=options.spy, output_fn=options.repl_output_fn)
  File "c:\users\me\documents\github\hy\hy\cmdline.py", line 231, in run_repl
    os=platform.system()
  File "C:\Users\ME\AppData\Local\Programs\Python\Python36\lib\code.py", line 233, in interact
    more = self.push(line)
  File "C:\Users\ME\AppData\Local\Programs\Python\Python36\lib\code.py", line 259, in push
    more = self.runsource(source, self.filename)
  File "c:\users\me\documents\github\hy\hy\cmdline.py", line 118, in runsource
    print(self.output_fn(value))
  File "<eval_body>", line 1, in __repr__
ZeroDivisionError: division by zero

(hy36-gilch) C:\Users\ME\Documents\GitHub\hy>
```
It should just report the exception like Python does, not quit the repl.

Discussion:

Patch:
diff --git a/NEWS b/NEWS
index 468d884a..3e23f668 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ Changes from 0.13.0
    * Fixed a crash when `macroexpand`ing a macro with a named import
    * Fixed a crash when `with` suppresses an exception. `with` now returns
      `None` in this case.
+   * Fixed a crash when --repl-output-fn raises an exception
    * `assoc` now evaluates its arguments only once each
    * `break` and `continue` now raise an error when given arguments
      instead of silently ignoring them
diff --git a/hy/cmdline.py b/hy/cmdline.py
index a9d966c0..fb585392 100644
--- a/hy/cmdline.py
+++ b/hy/cmdline.py
@@ -115,7 +115,12 @@ class HyREPL(code.InteractiveConsole):
             # the user as `_`.
             self.locals['_'] = value
             # Print the value.
-            print(self.output_fn(value))
+            try:
+                output = self.output_fn(value)
+            except Exception:
+                self.showtraceback()
+                return False
+            print(output)
         return False
 
 


Test patch:
diff --git a/tests/test_bin.py b/tests/test_bin.py
index 6df4d437..670b77a2 100644
--- a/tests/test_bin.py
+++ b/tests/test_bin.py
@@ -132,6 +132,16 @@ def test_bin_hy_stdin_except_do():
     assert "zzz" in output
 
 
+def test_bin_hy_stdin_bad_repr():
+    # https://github.com/hylang/hy/issues/1389
+    output, err = run_cmd("hy", """
+         (defclass BadRepr [] (defn __repr__ [self] (/ 0)))
+         (BadRepr)
+         (+ "A" "Z")""")
+    assert "ZeroDivisionError" in err
+    assert "AZ" in output
+
+
 def test_bin_hy_stdin_hy_repr():
     output, _ = run_cmd("hy", '(+ [1] [2])')
     assert "[1, 2]" in output.replace('L', '')