-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add `SpanException` to be attached to spans * Add `SpanExceptionRecorder` to describe how a span should behave when recording exceptions * Conform `Span` to `SpanExceptionRecorder` * Extend `Span` to also allow usage of `Error` for recording exceptions
- Loading branch information
1 parent
b22dd41
commit 6d6cb71
Showing
10 changed files
with
490 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import Foundation | ||
|
||
/// An interface that represents an exception that can be attached to a span. | ||
public protocol SpanException { | ||
var type: String { get } | ||
var message: String? { get } | ||
var stackTrace: [String]? { get } | ||
} | ||
|
||
extension NSError: SpanException { | ||
public var type: String { | ||
String(reflecting: self) | ||
} | ||
|
||
public var message: String? { | ||
localizedDescription | ||
} | ||
|
||
public var stackTrace: [String]? { | ||
nil | ||
} | ||
} | ||
|
||
#if !os(Linux) | ||
extension NSException: SpanException { | ||
public var type: String { | ||
name.rawValue | ||
} | ||
|
||
public var message: String? { | ||
reason | ||
} | ||
|
||
public var stackTrace: [String]? { | ||
callStackSymbols | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
Tests/OpenTelemetryApiTests/Trace/SpanExceptionTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import Foundation | ||
import XCTest | ||
import OpenTelemetryApi | ||
|
||
final class SpanExceptionTests: XCTestCase { | ||
func testErrorAsSpanException() { | ||
enum TestError: Error { | ||
case test(code: Int) | ||
} | ||
|
||
let error = TestError.test(code: 5) | ||
|
||
// `Error` can be converted to `NSError`, which automatically makes the cast to | ||
// `SpanException` possible since `NSError` conforms to `SpanException`. | ||
let exception = error as SpanException | ||
|
||
XCTAssertEqual(exception.type, String(reflecting: error)) | ||
XCTAssertEqual(exception.message, error.localizedDescription) | ||
XCTAssertNil(exception.stackTrace) | ||
} | ||
|
||
func testCustomNSErrorAsSpanException() throws { | ||
struct TestCustomNSError: Error, CustomNSError { | ||
let additionalComments: String | ||
|
||
var errorUserInfo: [String : Any] { | ||
[NSLocalizedDescriptionKey: "This is a custom NSError: \(additionalComments)"] | ||
} | ||
} | ||
|
||
let error = TestCustomNSError(additionalComments: "SpanExceptionTests") | ||
|
||
// `Error` can be converted to `NSError`, which automatically makes the cast to | ||
// `SpanException` possible since `NSError` conforms to `SpanException`. | ||
let exception = error as SpanException | ||
|
||
XCTAssertEqual(exception.type, String(reflecting: error)) | ||
XCTAssertEqual(exception.message, error.localizedDescription) | ||
XCTAssertNil(exception.stackTrace) | ||
|
||
// `TestCustomNSError` conforms to `CustomNSError`, so the conversion to `NSError` when casting to | ||
// `SpanException` should utilize that protocol and result in a custom `localizedDescription`. | ||
let localizedDescription = try XCTUnwrap(error.errorUserInfo[NSLocalizedDescriptionKey] as? String) | ||
XCTAssertEqual(exception.message, localizedDescription) | ||
} | ||
|
||
func testNSError() { | ||
let nsError = NSError(domain: "Test Domain", code: 1) | ||
let exception = nsError as SpanException | ||
|
||
XCTAssertEqual(exception.type, String(reflecting: nsError)) | ||
XCTAssertEqual(exception.message, nsError.localizedDescription) | ||
XCTAssertNil(exception.stackTrace) | ||
} | ||
|
||
#if !os(Linux) | ||
func testNSException() { | ||
final class TestException: NSException { | ||
override var callStackSymbols: [String] { | ||
[ | ||
"test-stack-entry-1", | ||
"test-stack-entry-2", | ||
"test-stack-entry-3" | ||
] | ||
} | ||
} | ||
|
||
let exceptionReason = "This is a test exception" | ||
let nsException = TestException(name: .genericException, reason: exceptionReason) | ||
let exception = nsException as SpanException | ||
|
||
XCTAssertEqual(exception.type, nsException.name.rawValue) | ||
XCTAssertEqual(exception.message, nsException.reason) | ||
XCTAssertEqual(exception.stackTrace, nsException.callStackSymbols) | ||
} | ||
#endif | ||
} |
Oops, something went wrong.