|
2 | 2 | """Some generic utilities for dealing with classes, urls, and serialization."""
|
3 | 3 | # Copyright (c) IPython Development Team.
|
4 | 4 | # Distributed under the terms of the Modified BSD License.
|
| 5 | +import asyncio |
| 6 | +import functools |
| 7 | +import inspect |
5 | 8 | import logging
|
6 | 9 | import os
|
7 | 10 | import re
|
|
23 | 26 | import zmq
|
24 | 27 | from dateutil.parser import parse as dateutil_parse
|
25 | 28 | from dateutil.tz import tzlocal
|
26 |
| -from decorator import decorator |
27 | 29 | from IPython import get_ipython
|
28 | 30 | from IPython.core.profiledir import ProfileDir
|
29 | 31 | from IPython.core.profiledir import ProfileDirError
|
@@ -101,17 +103,32 @@ def get(self, key, default=None):
|
101 | 103 | # -----------------------------------------------------------------------------
|
102 | 104 |
|
103 | 105 |
|
104 |
| -@decorator |
105 |
| -def log_errors(f, self, *args, **kwargs): |
| 106 | +def log_errors(f): |
106 | 107 | """decorator to log unhandled exceptions raised in a method.
|
107 | 108 |
|
108 | 109 | For use wrapping on_recv callbacks, so that exceptions
|
109 | 110 | do not cause the stream to be closed.
|
110 | 111 | """
|
111 |
| - try: |
112 |
| - return f(self, *args, **kwargs) |
113 |
| - except Exception as e: |
114 |
| - self.log.error("Uncaught exception in %r" % f, exc_info=True) |
| 112 | + |
| 113 | + @functools.wraps(f) |
| 114 | + def logs_errors(self, *args, **kwargs): |
| 115 | + try: |
| 116 | + result = f(self, *args, **kwargs) |
| 117 | + except Exception: |
| 118 | + self.log.error("Uncaught exception in {f}: {future.exception()}") |
| 119 | + return |
| 120 | + |
| 121 | + if inspect.isawaitable(result): |
| 122 | + # if it's async, schedule logging for when the future resolves |
| 123 | + future = asyncio.ensure_future(result) |
| 124 | + |
| 125 | + def _log_error(future): |
| 126 | + if future.exception(): |
| 127 | + self.log.error("Uncaught exception in {f}: {future.exception()}") |
| 128 | + |
| 129 | + future.add_done_callback(_log_error) |
| 130 | + |
| 131 | + return logs_errors |
115 | 132 |
|
116 | 133 |
|
117 | 134 | def is_url(url):
|
|
0 commit comments