Skip to content

Instantly share code, notes, and snippets.

Last active Aug 21, 2020
What would you like to do?
AssertionFailure as a type
/// Boring setup. See below for the good parts
public class Logger {
public static let root = Logger(subsystem: .none, parent: nil)
public let subsystem: Subsystem
public let parent: Logger?
public init(subsystem: Subsystem, parent: Logger? = .root) {
self.subsystem = subsystem
self.parent = parent
// Fatals should go through something else like fatalError.
fileprivate func fatal(_ message: String, error: Error?, data: [String: Any] = [:], file: String = #file, line: Int = #line, function: String = #function) {
// Do what you want here
print("Logging: \(message)")
// All the gory internals of the logger....
// logInternal(message, data: add(error: error, to: data), level: .fatal, file: file, line: line, function: function)
// flush()
public struct Subsystem: Equatable, CustomStringConvertible {
public let name: String
public init(name: String) { = name
public var description: String { return name }
extension Subsystem {
public static var none: Subsystem { return Subsystem(name: "") }
public let Log = Logger.root
/// End boring setup.
/// The Good Parts
// WARNING: Constructing AssertionFailure calls assertionFailure()
struct AssertionFailure: Error {
let message: String
let file: StaticString
let line: Int
init(message: String, file: StaticString, line: Int) {
Swift.assertionFailure(message, file: file, line: UInt(line))
self.message = message
self.file = file
self.line = line
extension Logger {
public func assertionFailure(_ message: String = "", error: Error? = nil, data: [String: Any] = [:], file: StaticString = #file, line: Int = #line, function: String = #function)
-> Error {
// First, log it (and flush all the destinations)
fatal(message, error: error, data: data, file: String(describing: file), line: line)
// And then either crash (assertionFailure) or return it as an Error (which can be thrown)
return AssertionFailure(message: message, file: file, line: line)
// We can throw AssertionFailures
throw Log.assertionFailure("Bad")
// Or use them as Error values
// But also, they can be used without a logging system
throw AssertionFailure(message: "Bad")
// Probably possible to wrap `assert` in here somehow more directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment