@@ -240,10 +240,10 @@ def safe_repr(value):
240240def object_to_json (obj ):
241241 def _walk (obj , depth ):
242242 if depth < 4 :
243- if isinstance (obj , Sequence ):
243+ if isinstance (obj , Sequence ) and not isinstance ( obj , ( bytes , text_type )) :
244244 return [_walk (x , depth + 1 ) for x in obj ]
245245 if isinstance (obj , Mapping ):
246- return {safe_repr (k ): _walk (v , depth + 1 ) for k , v in obj .items ()}
246+ return {safe_str (k ): _walk (v , depth + 1 ) for k , v in obj .items ()}
247247 return safe_repr (obj )
248248
249249 return _walk (obj , 0 )
@@ -315,12 +315,63 @@ def exceptions_from_error_tuple(exc_type, exc_value, tb, with_locals=True):
315315 return rv
316316
317317
318- def create_event ():
319- return {
320- "event_id" : uuid .uuid4 ().hex ,
321- "timestamp" : datetime .utcnow ().strftime ("%Y-%m-%dT%H:%M:%SZ" ),
322- "level" : "error" ,
323- }
318+ class Event (Mapping ):
319+ __slots__ = ("_data" , "_exc_value" )
320+
321+ def __init__ (self ):
322+ self ._data = {
323+ "event_id" : uuid .uuid4 ().hex ,
324+ "timestamp" : datetime .utcnow ().strftime ("%Y-%m-%dT%H:%M:%SZ" ),
325+ "level" : "error" ,
326+ }
327+ self ._exc_value = None
328+
329+ def get_json (self ):
330+ return self ._data
331+
332+ def set_exception (self , exc_type , exc_value , tb , with_locals ):
333+ self ["exception" ] = {
334+ "values" : exceptions_from_error_tuple (exc_type , exc_value , tb , with_locals )
335+ }
336+ self ._exc_value = exc_value
337+
338+ def __getitem__ (self , key ):
339+ return self ._data [key ]
340+
341+ def __contains__ (self , key ):
342+ return key in self ._data
343+
344+ def get (self , * a , ** kw ):
345+ return self ._data .get (* a , ** kw )
346+
347+ def setdefault (self , * a , ** kw ):
348+ return self ._data .setdefault (* a , ** kw )
349+
350+ def __setitem__ (self , key , value ):
351+ self ._data [key ] = value
352+
353+ def __iter__ (self ):
354+ return iter (self ._data )
355+
356+ def __len__ (self ):
357+ return len (self ._data )
358+
359+
360+ class DefaultEventProcessor (object ):
361+ def __init__ (self ):
362+ self ._most_recent_exception = None
363+
364+ def __call__ (self , event ):
365+ if event ._exc_value is None :
366+ return
367+ if self ._most_recent_exception is event ._exc_value :
368+ raise SkipEvent ()
369+ self ._most_recent_exception = event ._exc_value
370+
371+
372+ class SkipEvent (Exception ):
373+ """Risen from an event processor to indicate that the event should be
374+ ignored and not be reported."""
324375
325376
326377def to_string (value ):
0 commit comments