Skip to content

Abort and StackTrace improvements

Compare
Choose a tag to compare
@tanner0101 tanner0101 released this 15 Jun 22:58
2bfe714
This patch was authored and released by @tanner0101.

Abort now conforms to DebuggableError (#2400).

Abort now exposes source, reason, identifier, and stackTrace via the DebuggableError protocol.

⚠️ Abort.source is now an optional as required by DebuggableError.

Abort now captures StackTrace by default.

func foo() throws {
    try bar()
}
func bar() throws {
    try baz()
}
func baz() throws {
    throw Abort(.internalServerError, reason: "Oops")
}
do {
    try foo()
} catch let error as DebuggableError {
    XCTAssertContains(error.stackTrace?.frames[0].function, "baz")
    XCTAssertContains(error.stackTrace?.frames[1].function, "bar")
    XCTAssertContains(error.stackTrace?.frames[2].function, "foo")
}

To avoid capturing a stack trace, pass nil:

Abort(.internalServerError, reason: "Oops", stackTrace: nil)

To disable stack traces globally, use:

StackTrace.isCaptureEnabled = false

Improved StackTrace.capture on Linux (#2400).

StackTrace.capture on Linux now utilizes libbacktrace to provide symbol names.

0 VaporTests baz #1 () throws -> () in VaporTests.ErrorTests.testAbortDebuggable() throws -> ()
1 VaporTests bar #1 () throws -> () in VaporTests.ErrorTests.testAbortDebuggable() throws -> ()
2 VaporTests foo #1 () throws -> () in VaporTests.ErrorTests.testAbortDebuggable() throws -> ()
3 VaporTests VaporTests.ErrorTests.testAbortDebuggable() throws -> ()
...

StackFrame.capture now accepts an optional skip parameter. Use this to exclude any extraneous stack frames from the captured result.

// Captures stack trace, excluding this init call.
init(stackTrace: StackTrace? = .capture(skip: 1)) {
    ...
}