Skip to content

Commit bb8d7f4

Browse files
committed
Add Retry.Error.abort to be able to break out of retry block
1 parent ee6dc33 commit bb8d7f4

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

Sources/Retry/Retry.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import Foundation
1717

1818
public enum Retry {
1919
public enum Error: Swift.Error {
20-
case retryLimitExceeded(lastError: Swift.Error?)
20+
case abort(with: Swift.Error? = nil)
21+
case retryLimitExceeded(lastError: Swift.Error? = nil)
2122
}
2223

2324
public static func backedOffDelay(baseDelay: Double, attempt: Int) -> UInt32 {
@@ -39,6 +40,8 @@ public enum Retry {
3940
}
4041
do {
4142
return try block()
43+
} catch let Error.abort(with: error) {
44+
throw Error.abort(with: error)
4245
} catch {
4346
logger.onError(label: label, error: error)
4447
lastError = error
@@ -68,6 +71,8 @@ public enum Retry {
6871
}
6972
do {
7073
return try await block()
74+
} catch let Error.abort(with: error) {
75+
throw Error.abort(with: error)
7176
} catch {
7277
logger.onError(label: label, error: error)
7378
lastError = error

Tests/RetryTests/RetryTests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,29 @@ final class RetryTests: XCTestCase {
7676
XCTAssertEqual(called, 4)
7777
}
7878

79+
func test_attempt_abort() throws {
80+
var called = 0
81+
struct Error: Swift.Error, CustomStringConvertible {
82+
var description: String { "test error" }
83+
}
84+
85+
// MUT
86+
do {
87+
try Retry.attempt("", delay: 0, retries: 3) {
88+
called += 1
89+
throw Retry.Error.abort(with: Error())
90+
}
91+
XCTFail("expected an error to be thrown")
92+
} catch let Retry.Error.abort(with: .some(error)) {
93+
XCTAssertEqual("\(error)", "test error")
94+
} catch {
95+
XCTFail("unexpected error: \(error)")
96+
}
97+
98+
// validation
99+
XCTAssertEqual(called, 1)
100+
}
101+
79102
func test_attempt_async() async throws {
80103
func dummyAsyncFunction() async { }
81104
var called = 0

0 commit comments

Comments
 (0)