From f8eb5e72456efd7d4a5f6388b8a466d28e1e5e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 7 Aug 2020 16:27:33 +0200 Subject: [PATCH 01/12] Add example & explanation for exception.escaped. --- CHANGELOG.md | 2 +- .../trace/semantic_conventions/exceptions.md | 37 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d96cd1ef85..dff7abc8db4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ New: - Add Span API and semantic conventions for recording exceptions ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697)) * API was extended to allow adding arbitrary event attributes ([#874](https://github.com/open-telemetry/opentelemetry-specification/pull/874)) - * `exception.escaped` was added ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784)) + * `exception.escaped` was added ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784), [#???](https://github.com/open-telemetry/opentelemetry-specification/pull/784)) Updates: diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 35cb1a8085e..ef35db8345d 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,9 +13,44 @@ exceptions. ## Recording an Exception -An exception SHOULD be recorded as an `Event` on the span during which it occurred. +An exception that escapes the scope of a span SHOULD be recorded +as an `Event` on that span +(of course, other exceptions that are deemed relevant may also be recorded). +An exception is considered to have escaped the scope if the span is ended +while the exception is still "in flight". Note: + +* While it is usually not possible to determine whether some exception thrown + now *will* escape the scope of a span, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span. + See the [example below](#exception-end-example). +* Special considerations may apply for Go, where exception semantic conventions + might be used for non-exceptions. + See [issue #764](https://github.com/open-telemetry/opentelemetry-specification/issues/764). + The name of the event MUST be `"exception"`. +Note that multiple events (on the same or different Spans) might be logged +for the same exception object instance. +For example, one event might be logged in an instrumented exception constructor +and another event might be logged when an exception leaves the scope of a span. + + + +A typical template for an auto-instrumentation implementing this semantic convention +could look like this: + +```java +Span span = myTracer.startSpan(/*...*/); +try { + // original code +} catch (Throwable e) { + span.recordException(e); // We know that the exception is escaping here. + throw e; +} finally { + span.end(); +} +``` + ## Attributes The table below indicates which attributes should be added to the `Event` and From 9d1f3040b000d8fad94a32ded9287397baf4b920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 12:38:10 +0200 Subject: [PATCH 02/12] Reshuffle paragraphs. --- .../trace/semantic_conventions/exceptions.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index ef35db8345d..3f6df5c20b0 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,38 +13,25 @@ exceptions. ## Recording an Exception -An exception that escapes the scope of a span SHOULD be recorded -as an `Event` on that span -(of course, other exceptions that are deemed relevant may also be recorded). -An exception is considered to have escaped the scope if the span is ended -while the exception is still "in flight". Note: - -* While it is usually not possible to determine whether some exception thrown - now *will* escape the scope of a span, it is trivial to know that an exception - will escape, if one checks for an active exception just before ending the span. - See the [example below](#exception-end-example). -* Special considerations may apply for Go, where exception semantic conventions - might be used for non-exceptions. - See [issue #764](https://github.com/open-telemetry/opentelemetry-specification/issues/764). - The name of the event MUST be `"exception"`. Note that multiple events (on the same or different Spans) might be logged for the same exception object instance. For example, one event might be logged in an instrumented exception constructor -and another event might be logged when an exception leaves the scope of a span. +and another event might be logged when an exception escapes the scope of a span. A typical template for an auto-instrumentation implementing this semantic convention -could look like this: +using an [API-provided `recordException` method](../api.md#record-exception) +could look like this (pseudo-Java): ```java Span span = myTracer.startSpan(/*...*/); try { // original code } catch (Throwable e) { - span.recordException(e); // We know that the exception is escaping here. + span.recordException(e, Attributes.of("exception.escaped", true)); throw e; } finally { span.end(); @@ -61,7 +48,7 @@ their types. | exception.type | String | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. E.g. "java.net.ConnectException", "OSError" | One of `exception.type` or `exception.message` is required | | exception.message | String | The exception message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | One of `exception.type` or `exception.message` is required | | exception.stacktrace | String | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. E.g. `"Exception in thread \"main\" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)"`. | No | -| exception.escaped | Bool | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span (e.g. if there is an exception active just before ending the span). Note that an exception may still leave the scope of the span even if this was not set or set to false, if the event was recorded at an earlier time. | No | +| exception.escaped | Bool | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. See [explanation below](#escaped-exceptions). | No | ### Stacktrace Representation @@ -92,3 +79,16 @@ grained information from a stacktrace, if necessary. [csharp-stacktrace]: https://docs.microsoft.com/en-us/dotnet/api/system.exception.tostring [go-stacktrace]: https://golang.org/pkg/runtime/debug/#Stack [telemetry-sdk-resource]: https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions#telemetry-sdk + +### Escaped exceptions + +An exception is considered to have escaped (aka left) the scope of a span, +if that span is ended while the exception is still "in flight". + +While it is usually not possible to determine whether some exception thrown +now *will* escape the scope of a span, it is trivial to know that an exception +will escape, if one checks for an active exception just before ending the span. +See the [example above](#exception-end-example). It follows that an exception +may still escape the scope of the span even if the `exception.escaped` attribute +was not set or set to false, since that event might have been recorded at a time +where it was not clear whether the exception will escape. From 06f7c557a893f7e434ae451360db496d343ff896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 12:39:06 +0200 Subject: [PATCH 03/12] Remove potentially controversial changes. --- specification/trace/semantic_conventions/exceptions.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 3f6df5c20b0..4cd26b00e96 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,13 +13,9 @@ exceptions. ## Recording an Exception +An exception SHOULD be recorded as an `Event` on the span during which it occurred. The name of the event MUST be `"exception"`. -Note that multiple events (on the same or different Spans) might be logged -for the same exception object instance. -For example, one event might be logged in an instrumented exception constructor -and another event might be logged when an exception escapes the scope of a span. - A typical template for an auto-instrumentation implementing this semantic convention From a47eceeda7b1284313f9754a313ac4b207926576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 12:49:56 +0200 Subject: [PATCH 04/12] Fill in CHANGELOG link. --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dff7abc8db4..5d812711f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,9 @@ New: - Add Span API and semantic conventions for recording exceptions ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697)) * API was extended to allow adding arbitrary event attributes ([#874](https://github.com/open-telemetry/opentelemetry-specification/pull/874)) - * `exception.escaped` was added ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784), [#???](https://github.com/open-telemetry/opentelemetry-specification/pull/784)) + * `exception.escaped` was added + ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784), + [#946](https://github.com/open-telemetry/opentelemetry-specification/pull/946)) Updates: From 7f9ed3506e1258293b27ba9a9118833de1bfa050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 17:11:12 +0200 Subject: [PATCH 05/12] Address review comments. --- specification/trace/semantic_conventions/exceptions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 4cd26b00e96..59bbff151ea 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -25,12 +25,12 @@ could look like this (pseudo-Java): ```java Span span = myTracer.startSpan(/*...*/); try { - // original code + // Code that does the actual work which the Span represents } catch (Throwable e) { - span.recordException(e, Attributes.of("exception.escaped", true)); - throw e; + span.recordException(e, Attributes.of("exception.escaped", true)); + throw e; } finally { - span.end(); + span.end(); } ``` From 370759b4aeb0bd7891dca0d34e409a8635142f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 17:11:22 +0200 Subject: [PATCH 06/12] Wording Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- specification/trace/semantic_conventions/exceptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 59bbff151ea..4c99dbe922b 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -78,7 +78,7 @@ grained information from a stacktrace, if necessary. ### Escaped exceptions -An exception is considered to have escaped (aka left) the scope of a span, +An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still "in flight". While it is usually not possible to determine whether some exception thrown From d359f477017d4ec0f71191eabae6b1edecee79fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 14 Sep 2020 19:34:09 +0200 Subject: [PATCH 07/12] Use actual OTel-Java API. --- specification/trace/semantic_conventions/exceptions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 4c99dbe922b..154e9f931e0 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -27,7 +27,8 @@ Span span = myTracer.startSpan(/*...*/); try { // Code that does the actual work which the Span represents } catch (Throwable e) { - span.recordException(e, Attributes.of("exception.escaped", true)); + span.recordException(e, Attributes.of( + "exception.escaped", AttributeValue.booleanAttributeValue(true))); throw e; } finally { span.end(); From f78003e43bf40a15e4995ff9a41a70cb0ee2e865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 15 Sep 2020 08:54:06 +0200 Subject: [PATCH 08/12] Revert "Use actual OTel-Java API." This reverts commit d359f477017d4ec0f71191eabae6b1edecee79fb. --- specification/trace/semantic_conventions/exceptions.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 154e9f931e0..4c99dbe922b 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -27,8 +27,7 @@ Span span = myTracer.startSpan(/*...*/); try { // Code that does the actual work which the Span represents } catch (Throwable e) { - span.recordException(e, Attributes.of( - "exception.escaped", AttributeValue.booleanAttributeValue(true))); + span.recordException(e, Attributes.of("exception.escaped", true)); throw e; } finally { span.end(); From e363eaf6883ee4d26e072ed6c4a55fe9397c59ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 15 Sep 2020 18:36:20 +0200 Subject: [PATCH 09/12] Clarify CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d812711f55..51efc366acc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,10 +19,10 @@ New: ([#606](https://github.com/open-telemetry/opentelemetry-specification/pull/606/)) - Clarification of the behavior of the Trace API, re: context propagation, in the absence of an installed SDK -- Add Span API and semantic conventions for recording exceptions +- Add API and semantic conventions for recording exceptions as Span Events ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697)) * API was extended to allow adding arbitrary event attributes ([#874](https://github.com/open-telemetry/opentelemetry-specification/pull/874)) - * `exception.escaped` was added + * `exception.escaped` sematic span event attribute was added ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784), [#946](https://github.com/open-telemetry/opentelemetry-specification/pull/946)) From 83ab7b611523684107b2997b2dfb530c456ab9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 18 Sep 2020 16:19:12 +0200 Subject: [PATCH 10/12] Re-generate tables. --- semantic_conventions/trace/exception.yaml | 15 +++++++++++---- .../trace/semantic_conventions/exceptions.md | 13 ++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/semantic_conventions/trace/exception.yaml b/semantic_conventions/trace/exception.yaml index 612eaa04026..0406f496c09 100644 --- a/semantic_conventions/trace/exception.yaml +++ b/semantic_conventions/trace/exception.yaml @@ -29,11 +29,18 @@ groups: type: boolean brief: > SHOULD be set to true if the exception event is recorded at a point where - it is known that the exception is escaping the scope of the span (e.g. if - there is an exception active just before ending the span). + it is known that the exception is escaping the scope of the span. note: > - Note that an exception may still leave the scope of the span even if this - was not set or set to false, if the event was recorded at an earlier time. + An exception is considered to have escaped (or left) the scope of a span, + if that span is ended while the exception is still "in flight". + + While it is usually not possible to determine whether some exception thrown + now *will* escape the scope of a span, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span. + See the [example above](#exception-end-example). It follows that an exception + may still escape the scope of the span even if the `exception.escaped` attribute + was not set or set to false, since that event might have been recorded at a time + where it was not clear whether the exception will escape. constraints: - any_of: - "exception.type" diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 22a28ba796e..59bd38c74bb 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -47,16 +47,8 @@ their types. | `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | No | | `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | No | -**[1]:** An exception is considered to have escaped (or left) the scope of a span, -if that span is ended while the exception is still "in flight". - -While it is usually not possible to determine whether some exception thrown -now *will* escape the scope of a span, it is trivial to know that an exception -will escape, if one checks for an active exception just before ending the span. -See the [example above](#exception-end-example). It follows that an exception -may still escape the scope of the span even if the `exception.escaped` attribute -was not set or set to false, since that event might have been recorded at a time -where it was not clear whether the exception will escape. +**[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still "in flight". +While it is usually not possible to determine whether some exception thrown now *will* escape the scope of a span, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span. See the [example above](#exception-end-example). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, since that event might have been recorded at a time where it was not clear whether the exception will escape. **Additional attribute requirements:** At least one of the following sets of attributes is required: @@ -93,4 +85,3 @@ grained information from a stacktrace, if necessary. [csharp-stacktrace]: https://docs.microsoft.com/en-us/dotnet/api/system.exception.tostring [go-stacktrace]: https://golang.org/pkg/runtime/debug/#Stack [telemetry-sdk-resource]: https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions#telemetry-sdk - From b4fa4242c7d98c54c9822ae0c0a4a1c4a81ad63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 18 Sep 2020 16:21:09 +0200 Subject: [PATCH 11/12] Typo in CHANGELOG.md Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f25d91505ca..853da2c3161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ New: - Add API and semantic conventions for recording exceptions as Span Events ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697)) * API was extended to allow adding arbitrary event attributes ([#874](https://github.com/open-telemetry/opentelemetry-specification/pull/874)) - * `exception.escaped` sematic span event attribute was added + * `exception.escaped` semantic span event attribute was added ([#784](https://github.com/open-telemetry/opentelemetry-specification/pull/784), [#946](https://github.com/open-telemetry/opentelemetry-specification/pull/946)) From 350ff891f5786fcfdce60c4c4374cbf0beea7259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Sat, 19 Sep 2020 13:04:08 +0200 Subject: [PATCH 12/12] Clarify exception escaped description. --- semantic_conventions/trace/exception.yaml | 25 ++++++++++++------- .../trace/semantic_conventions/exceptions.md | 18 +++++++++++-- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/semantic_conventions/trace/exception.yaml b/semantic_conventions/trace/exception.yaml index 0406f496c09..beaafdb93b1 100644 --- a/semantic_conventions/trace/exception.yaml +++ b/semantic_conventions/trace/exception.yaml @@ -30,17 +30,24 @@ groups: brief: > SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. - note: > + note: |- An exception is considered to have escaped (or left) the scope of a span, - if that span is ended while the exception is still "in flight". + if that span is ended while the exception is still logically "in flight". + This may be actually "in flight" in some languages (e.g. if the exception + is passed to a Context manager's `__exit__` method in Python) but will + usually be caught at the point of recording the exception in most languages. + + It is usually not possible to determine at the point where an exception is thrown + whether it will escape the scope of a span. + However, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span, + as done in the [example above](#exception-end-example). + + It follows that an exception may still escape the scope of the span + even if the `exception.escaped` attribute was not set or set to false, + since the event might have been recorded at a time where it was not + clear whether the exception will escape. - While it is usually not possible to determine whether some exception thrown - now *will* escape the scope of a span, it is trivial to know that an exception - will escape, if one checks for an active exception just before ending the span. - See the [example above](#exception-end-example). It follows that an exception - may still escape the scope of the span even if the `exception.escaped` attribute - was not set or set to false, since that event might have been recorded at a time - where it was not clear whether the exception will escape. constraints: - any_of: - "exception.type" diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 59bd38c74bb..f975cc3ed8a 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -47,8 +47,22 @@ their types. | `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | No | | `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | No | -**[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still "in flight". -While it is usually not possible to determine whether some exception thrown now *will* escape the scope of a span, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span. See the [example above](#exception-end-example). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, since that event might have been recorded at a time where it was not clear whether the exception will escape. +**[1]:** An exception is considered to have escaped (or left) the scope of a span, +if that span is ended while the exception is still logically "in flight". +This may be actually "in flight" in some languages (e.g. if the exception +is passed to a Context manager's `__exit__` method in Python) but will +usually be caught at the point of recording the exception in most languages. + +It is usually not possible to determine at the point where an exception is thrown +whether it will escape the scope of a span. +However, it is trivial to know that an exception +will escape, if one checks for an active exception just before ending the span, +as done in the [example above](#exception-end-example). + +It follows that an exception may still escape the scope of the span +even if the `exception.escaped` attribute was not set or set to false, +since the event might have been recorded at a time where it was not +clear whether the exception will escape. **Additional attribute requirements:** At least one of the following sets of attributes is required: