Skip to content

Commit 7d2bbea

Browse files
committed
Attempting to apply/revert a failed hook now throws error
1 parent c3099fb commit 7d2bbea

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

Sources/InterposeKit/Hooks/Hook.swift

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,27 +120,37 @@ public final class Hook {
120120

121121
/// Applies the hook by interposing the method implementation.
122122
public func apply() throws {
123-
guard self.state == .pending else { return }
124-
125-
do {
126-
try self.strategy.replaceImplementation()
127-
self.state = .active
128-
} catch {
129-
self.state = .failed
130-
throw error
123+
switch self.state {
124+
case .pending:
125+
do {
126+
try self.strategy.replaceImplementation()
127+
self.state = .active
128+
} catch {
129+
self.state = .failed
130+
throw error
131+
}
132+
case .failed:
133+
throw InterposeError.hookInFailedState
134+
case .active:
135+
return
131136
}
132137
}
133138

134139
/// Reverts the hook, restoring the original method implementation.
135140
public func revert() throws {
136-
guard self.state == .active else { return }
137-
138-
do {
139-
try self.strategy.restoreImplementation()
140-
self.state = .pending
141-
} catch {
142-
self.state = .failed
143-
throw error
141+
switch self.state {
142+
case .active:
143+
do {
144+
try self.strategy.restoreImplementation()
145+
self.state = .pending
146+
} catch {
147+
self.state = .failed
148+
throw error
149+
}
150+
case .failed:
151+
throw InterposeError.hookInFailedState
152+
case .pending:
153+
return
144154
}
145155
}
146156

Sources/InterposeKit/InterposeError.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import Foundation
22

33
public enum InterposeError: Error {
44

5+
/// A hook operation failed and the hook is no longer usable.
6+
case hookInFailedState
7+
58
/// No instance method found for the selector on the specified class.
69
///
710
/// This typically occurs when mistyping a stringified selector or attempting to interpose
@@ -165,6 +168,14 @@ extension InterposeError: Equatable {
165168
default:
166169
return false
167170
}
171+
172+
case .hookInFailedState:
173+
switch rhs {
174+
case .hookInFailedState:
175+
return true
176+
default:
177+
return false
178+
}
168179
}
169180
}
170181
}

Tests/InterposeKitTests/ClassHookTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@ final class ClassHookTests: XCTestCase {
293293
hook.debugDescription,
294294
#"^Failed hook for -\[ExampleClass doSomething\]$"#
295295
)
296+
297+
XCTAssertThrowsError(
298+
try hook.revert(),
299+
expected: InterposeError.hookInFailedState
300+
)
296301
}
297302

298303
func testCleanUp_implementationPreserved() throws {

0 commit comments

Comments
 (0)