Skip to content

Commit 4c0e715

Browse files
committed
Fix error of "serialize" with "catch()" / "opt(record=True)" (#286)
1 parent b8e9575 commit 4c0e715

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
- Modify the way the ``extra`` dict is used by ``LogRecord`` in order to prevent possible ``KeyError`` with standard ``logging`` handlers (`#271 <https://github.com/Delgan/loguru/issues/271>`_).
55
- Add a new ``default`` optional argument to ``logger.catch()``, it should be the returned value by the decorated function in case an error occurred (`#272 <https://github.com/Delgan/loguru/issues/272>`_).
6+
- Fix ``ValueError`` when using ``serialize=True`` in combination with ``logger.catch()`` or ``logger.opt(record=True)`` due to circular reference of the ``record`` dict (`#286 <https://github.com/Delgan/loguru/issues/286>`_).
67

78

89
`0.5.0`_ (2020-05-17)

loguru/_logger.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,9 @@ def _log(self, level_id, static_level_no, from_decorator, options, message, args
19261926
args = [arg() for arg in args]
19271927
kwargs = {key: value() for key, value in kwargs.items()}
19281928

1929+
if capture and kwargs:
1930+
log_record["extra"].update(kwargs)
1931+
19291932
if record:
19301933
if "record" in kwargs:
19311934
raise TypeError(
@@ -1934,9 +1937,6 @@ def _log(self, level_id, static_level_no, from_decorator, options, message, args
19341937
)
19351938
kwargs.update(record=log_record)
19361939

1937-
if capture and kwargs:
1938-
log_record["extra"].update(kwargs)
1939-
19401940
if colors:
19411941
if args or kwargs:
19421942
colored_message = Colorizer.prepare_message(message, args, kwargs)

tests/test_add_option_serialize.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ def test_serialize_with_exception():
3636
assert bool(sink.json["record"]["exception"])
3737

3838

39+
def test_serialize_with_catch_decorator():
40+
sink = JsonSink()
41+
logger.add(sink, format="{message}", serialize=True, catch=False)
42+
43+
@logger.catch
44+
def foo():
45+
1 / 0
46+
47+
foo()
48+
49+
lines = sink.json["text"].splitlines()
50+
assert lines[0].startswith("An error has been caught")
51+
assert lines[-1] == "ZeroDivisionError: division by zero"
52+
assert bool(sink.json["record"]["exception"])
53+
54+
55+
def test_serialize_with_record_option():
56+
sink = JsonSink()
57+
logger.add(sink, format="{message}", serialize=True, catch=False)
58+
59+
logger.opt(record=True).info("Test", foo=123)
60+
61+
assert sink.json["text"] == "Test\n"
62+
assert sink.dict["extra"] == {"foo": 123}
63+
64+
3965
def test_serialize_not_serializable():
4066
sink = JsonSink()
4167
logger.add(sink, format="{message}", catch=False, serialize=True)

tests/test_opt.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,35 @@ def test_record_in_kwargs_too(writer):
2222
logger.opt(record=True).info("Foo {record}", record=123)
2323

2424

25+
def test_record_not_in_extra():
26+
extra = None
27+
28+
def sink(message):
29+
nonlocal extra
30+
extra = message.record["extra"]
31+
32+
logger.add(sink, catch=False)
33+
34+
logger.opt(record=True).info("Test")
35+
36+
assert extra == {}
37+
38+
39+
def test_kwargs_in_extra_of_record():
40+
message = None
41+
42+
def sink(message_):
43+
nonlocal message
44+
message = message_
45+
46+
logger.add(sink, format="{message}", catch=False)
47+
48+
logger.opt(record=True).info("Test {record[extra][foo]}", foo=123)
49+
50+
assert message == "Test 123\n"
51+
assert message.record["extra"] == {"foo": 123}
52+
53+
2554
def test_exception_boolean(writer):
2655
logger.add(writer, format="{level.name}: {message}")
2756

0 commit comments

Comments
 (0)