def test_only_requires_only_type_or_value(self): SingleException.to_python(dict( type='ValueError', )) SingleException.to_python(dict( value='ValueError', ))
def test_handles_type_in_value(self): result = SingleException.to_python(dict(value="ValueError: unauthorized")) assert result.type == "ValueError" assert result.value == "unauthorized" result = SingleException.to_python(dict(value="ValueError:unauthorized")) assert result.type == "ValueError" assert result.value == "unauthorized"
def test_handles_type_in_value(self): result = SingleException.to_python( dict(value='ValueError: unauthorized', )) assert result.type == 'ValueError' assert result.value == 'unauthorized' result = SingleException.to_python( dict(value='ValueError:unauthorized', )) assert result.type == 'ValueError' assert result.value == 'unauthorized'
def test_handles_type_in_value(self): result = SingleException.to_python(dict( value='ValueError: unauthorized', )) assert result.type == 'ValueError' assert result.value == 'unauthorized' result = SingleException.to_python(dict( value='ValueError:unauthorized', )) assert result.type == 'ValueError' assert result.value == 'unauthorized'
def test_value_serialization_idempotent(self): result = SingleException.to_python({ 'type': None, 'value': {'unauthorized': True}, }).to_json() assert result['type'] is None assert result['value'] == '{"unauthorized":true}' # Don't re-split a json-serialized value on the colon result = SingleException.to_python(result).to_json() assert result['type'] is None assert result['value'] == '{"unauthorized":true}'
def test_value_serialization_idempotent(self): result = SingleException.to_python({ 'type': None, 'value': {'unauthorized': True}, }).to_json() assert 'type' not in result assert result['value'] == '{"unauthorized":true}' # Don't re-split a json-serialized value on the colon result = SingleException.to_python(result).to_json() assert 'type' not in result assert result['value'] == '{"unauthorized":true}'
def test_throws_away_empty_stacktrace(self): result = SingleException.to_python(dict( type='ValueError', value='foo', stacktrace={'frames': []}, )) assert not result.stacktrace
def interface(self): return SingleException.to_python( dict( type='ValueError', value='hello world', module='foo.bar', ))
def test_coerces_object_value_to_string(self): result = SingleException.to_python( dict( type='ValueError', value={'unauthorized': True}, )) assert result.value == '{"unauthorized":true}'
def test_coerces_object_value_to_string(self): result = SingleException.to_python({ 'type': 'ValueError', 'value': { 'unauthorized': True }, }) assert result.value == '{"unauthorized":true}'
def interface(self): return SingleException.to_python( dict( type='ValueError', value='hello world', module='foo.bar', ) )
def single_exception(interface: SingleException, event: Event, context: GroupingContext, **meta: Any) -> ReturnedVariants: type_component = GroupingComponent( id="type", values=[interface.type] if interface.type else [], similarity_encoder=ident_encoder, ) system_type_component = type_component.shallow_copy() ns_error_component = None if interface.mechanism: if interface.mechanism.synthetic: # Ignore synthetic exceptions as they are produced from platform # specific error codes. # # For example there can be crashes with EXC_ACCESS_VIOLATION_* on Windows with # the same exact stacktrace as a crash with EXC_BAD_ACCESS on macOS. # # Do not update type component of system variant, such that regex # can be continuously modified without unnecessarily creating new # groups. type_component.update( contributes=False, hint="ignored because exception is synthetic") if interface.mechanism.meta and "ns_error" in interface.mechanism.meta: ns_error_component = GroupingComponent( id="ns-error", values=[ interface.mechanism.meta["ns_error"].get("domain"), interface.mechanism.meta["ns_error"].get("code"), ], ) if interface.stacktrace is not None: with context: context["exception_data"] = interface.to_json() stacktrace_variants = context.get_grouping_component( interface.stacktrace, event=event, **meta) else: stacktrace_variants = { "app": GroupingComponent(id="stacktrace"), } rv = {} for variant, stacktrace_component in stacktrace_variants.items(): values = [ stacktrace_component, system_type_component if variant == "system" else type_component, ] if ns_error_component is not None: values.append(ns_error_component) if context["with_exception_value_fallback"]: value_component = GroupingComponent( id="value", similarity_encoder=text_shingle_encoder(5)) value_in = interface.value if value_in is not None: value_trimmed = trim_message_for_grouping(value_in) hint = "stripped common values" if value_in != value_trimmed else None if value_trimmed: value_component.update(values=[value_trimmed], hint=hint) if stacktrace_component.contributes and value_component.contributes: value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because stacktrace takes precedence", ) if (ns_error_component is not None and ns_error_component.contributes and value_component.contributes): value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because ns-error info takes precedence", ) values.append(value_component) rv[variant] = GroupingComponent(id="exception", values=values) return rv
def test_throws_away_empty_stacktrace(self): result = SingleException.to_python(dict(type="ValueError", value="foo", stacktrace={"frames": []})) assert not result.stacktrace
def test_coerces_object_value_to_string(self): result = SingleException.to_python(dict( type='ValueError', value={'unauthorized': True}, )) assert result.value == '{"unauthorized":true}'
def interface(self): return SingleException.to_python(dict(type="ValueError", value="hello world", module="foo.bar"))
def test_coerces_object_value_to_string(self): result = SingleException.to_python({ 'type': 'ValueError', 'value': {'unauthorized': True}, }) assert result.value == '{"unauthorized":true}'