4
4
import os
5
5
import sys
6
6
7
- from honeybadger .payload import create_payload , error_payload , server_payload
7
+ from honeybadger .payload import (
8
+ create_payload ,
9
+ error_payload ,
10
+ server_payload ,
11
+ MAX_CAUSE_DEPTH ,
12
+ )
8
13
from honeybadger .config import Configuration
9
14
10
15
from mock import patch
@@ -93,6 +98,15 @@ def test_error_payload_source_missing_file(_isfile):
93
98
assert payload ["backtrace" ][0 ]["source" ] == {}
94
99
95
100
101
+ def test_payload_with_no_exception_cause ():
102
+ with mock_traceback () as traceback_mock :
103
+ config = Configuration ()
104
+ exception = Exception ("Test" )
105
+
106
+ payload = error_payload (exc_traceback = None , exception = exception , config = config )
107
+ assert len (payload ["causes" ]) == 0
108
+
109
+
96
110
def test_payload_captures_exception_cause ():
97
111
with mock_traceback () as traceback_mock :
98
112
config = Configuration ()
@@ -103,6 +117,52 @@ def test_payload_captures_exception_cause():
103
117
assert len (payload ["causes" ]) == 1
104
118
105
119
120
+ def test_payload_captures_short_exception_cause_chain ():
121
+ with mock_traceback () as traceback_mock :
122
+ config = Configuration ()
123
+ exception = Exception ("Inner test" )
124
+ innerException = Exception ("Inner exception" )
125
+ innerException .__cause__ = Exception ("Inner cause" )
126
+ exception .__cause__ = innerException
127
+
128
+ payload = error_payload (exc_traceback = None , exception = exception , config = config )
129
+ assert len (payload ["causes" ]) == 2
130
+
131
+
132
+ def test_payload_captures_circular_exception_cause_chain ():
133
+ with mock_traceback () as traceback_mock :
134
+ config = Configuration ()
135
+ exceptionA = Exception ("A" )
136
+ exceptionB = Exception ("B" )
137
+ exceptionA .__cause__ = exceptionB
138
+ exceptionB .__cause__ = exceptionA
139
+
140
+ payload = error_payload (exc_traceback = None , exception = exceptionA , config = config )
141
+ assert len (payload ["causes" ]) == MAX_CAUSE_DEPTH + 1
142
+ assert (
143
+ payload ["causes" ][- 1 ]["message" ]
144
+ == f"Exception cause chain truncated after { MAX_CAUSE_DEPTH } levels. Possible circular reference."
145
+ )
146
+
147
+
148
+ def test_payload_captures_deep_exception_cause_chain ():
149
+ with mock_traceback () as traceback_mock :
150
+ config = Configuration ()
151
+ root = Exception ("root" )
152
+ current = root
153
+ for i in range (MAX_CAUSE_DEPTH * 2 ):
154
+ e = Exception (i )
155
+ e .__cause__ = current
156
+ current = e
157
+
158
+ payload = error_payload (exc_traceback = None , exception = current , config = config )
159
+ assert len (payload ["causes" ]) == MAX_CAUSE_DEPTH + 1
160
+ assert (
161
+ payload ["causes" ][- 1 ]["message" ]
162
+ == f"Exception cause chain truncated after { MAX_CAUSE_DEPTH } levels. Possible circular reference."
163
+ )
164
+
165
+
106
166
def test_error_payload_with_nested_exception ():
107
167
with mock_traceback () as traceback_mock :
108
168
config = Configuration ()
0 commit comments