Last active
August 17, 2017 06:56
-
-
Save nicklockwood/8abb014e00227554b653f7f466514d17 to your computer and use it in GitHub Desktop.
Typed error use-case example
This file contains hidden or 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
enum ValueError: Error { | |
case notFound | |
case typeMismatch | |
} | |
struct PropertyError: Error { | |
let name: String | |
let error: ValueError | |
} | |
struct ClassError: Error { | |
let name: String | |
let error: PropertyError | |
} | |
class Foo { | |
private func validateValue(_ value: Any) throws { // throws ValueError | |
... some logic | |
throw ValueError.typeMismatch | |
} | |
private func validateProperty(name: String, value: Any) throws { // should only throw a PropertyError | |
if ... { | |
throw PropertyError(name: name, error: .notFound) | |
} | |
try validateValue(value) // Whoops, I forgot to wrap this, now the property name is lost | |
} | |
func validate(name: String) throws { // should only throw a ClassError | |
do { | |
for (name, value) in self.properties { | |
try validateProperty(name: name, value: value) | |
} | |
} catch let error as PropertyError { | |
throw ClassError(name: name, error: error) | |
} | |
// Uh oh. Because of the bug earlier the ValueError falls through. It still gets passed | |
// to the caller, but now all they know is that there was a typeMismatch or notFound error | |
// - they've no idea which property or class it relates to. | |
// And note that having an explicit catch-all wouldn't help here either, because I'd still | |
// only have the ValueError - I wouldn't be able to convert it to the PropertyError that I | |
// need because I don't know which property failed validation. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment