Skip to content

Commit 8e47d1c

Browse files
committed
log_calls now logs exceptions.
1 parent d60a385 commit 8e47d1c

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

src/funlog/log_calls.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -197,29 +197,44 @@ def wrapper(*args, **kwargs):
197197
log_func(f"{EMOJI_CALL_BEGIN} Call: {call_str}")
198198

199199
start_time = time.time()
200-
201-
result = func(*args, **kwargs)
202-
203-
end_time = time.time()
204-
elapsed = end_time - start_time
205-
206-
if show_returns:
207-
if show_calls:
208-
# If we already logged the call, log the return in a corresponding style.
209-
return_msg = f"{EMOJI_CALL_END} Call done: {func_name}() took {format_duration(elapsed)}"
210-
else:
211-
return_msg = f"{EMOJI_TIMING} Call to {call_str} took {format_duration(elapsed)}"
212-
if show_return_value:
213-
log_func("%s: %s", return_msg, to_str(result))
214-
else:
200+
exception_info = None
201+
result = None
202+
try:
203+
result = func(*args, **kwargs)
204+
return result
205+
except Exception as e:
206+
exception_info = str(e)
207+
raise # Re-raise to preserve stack trace.
208+
finally:
209+
end_time = time.time()
210+
elapsed = end_time - start_time
211+
212+
if show_returns:
213+
if exception_info:
214+
return_msg = (
215+
f"{EMOJI_CALL_END} Exception: {func_name}(): "
216+
f"{abbrev_str(exception_info, truncate_length)}"
217+
)
218+
else:
219+
if show_calls:
220+
# If we already logged the call, log the return in a corresponding style.
221+
return_msg = (
222+
f"{EMOJI_CALL_END} Call done: {func_name}() "
223+
f"took {format_duration(elapsed)}"
224+
)
225+
else:
226+
return_msg = (
227+
f"{EMOJI_TIMING} Call to {call_str} took {format_duration(elapsed)}"
228+
)
229+
if show_return_value and not exception_info:
230+
log_func("%s: %s", return_msg, to_str(result))
231+
else:
232+
log_func("%s", return_msg)
233+
elif elapsed > if_slower_than:
234+
return_msg = (
235+
f"{EMOJI_TIMING} Call to {call_str} took {format_duration(elapsed)}"
236+
)
215237
log_func("%s", return_msg)
216-
elif elapsed > if_slower_than:
217-
return_msg = (
218-
f"{EMOJI_TIMING} Call to {call_str} took {format_duration(elapsed)}"
219-
)
220-
log_func("%s", return_msg)
221-
222-
return result
223238

224239
return cast(F, wrapper)
225240

@@ -232,7 +247,8 @@ def log_if_modifies(
232247
log_func: Optional[LogFunc] = None,
233248
) -> Callable[[F], F]:
234249
"""
235-
Decorator to log function calls if the returned value differs from the first argument input.
250+
Decorator to log function calls if the returned value differs from the first
251+
argument input. Does not log exceptions.
236252
"""
237253
log_func = _get_log_func(level, log_func)
238254

src/funlog/tally_calls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def tally_calls(
4040
Decorator to monitor performance by tallying function calls and total runtime, only logging
4141
periodically (every time calls exceed `periodic_ratio` more in count or runtime than the last
4242
time it was logged) or if runtime is greater than `if_slower_than` seconds).
43+
44+
Currently does not log exceptions.
4345
"""
4446

4547
log_func = _get_log_func(level, log_func)
@@ -112,9 +114,7 @@ def log_tallies(
112114
with _tallies_lock:
113115
tallies_copy = {k: replace(t) for k, t in _tallies.items()}
114116

115-
tallies_to_log = {
116-
k: t for k, t in tallies_copy.items() if t.total_time >= if_slower_than
117-
}
117+
tallies_to_log = {k: t for k, t in tallies_copy.items() if t.total_time >= if_slower_than}
118118
if tallies_to_log:
119119
log_lines = []
120120
log_lines.append(f"{EMOJI_TIMING} Function tallies:")

0 commit comments

Comments
 (0)