Repository: vapor/vapor
File: Sources/Vapor/Logging/Logger+Report.swift (Swift)

Code before:
        let source: ErrorSource?
        let reason: String
        let level: Logger.Level
        switch error {
        case let debuggable as DebuggableError:
            if self.logLevel <= .trace {
                reason = debuggable.debuggableHelp(format: .long)
            } else {
                reason = debuggable.debuggableHelp(format: .short)
            }
            source = debuggable.source
            level = debuggable.logLevel
        case let abort as AbortError:
            reason = abort.reason
            source = nil
            level = .warning
        case let encoding as EncodingError:
            reason = "\(encoding)"
            source = nil
            level = .warning
        case let decoding as DecodingError:
            reason = "\(decoding)"
            source = nil
            level = .warning
        case let localized as LocalizedError:
            reason = localized.errorDescription ?? "\(localized)"
            source = nil
            level = .warning
        default:
            reason = String(reflecting: error)
            source = nil
            level = .warning
        }
        
        self.log(
            level: level,
            .init(stringLiteral: reason),
            file: source?.file ?? file,
            function: source?.function ?? function,
            line: numericCast(source?.line ?? line)
        )
    }
}


Review comment (bug):
I would prefer that we just remove the `as LocalizedError` case altogether and let it fall through to the default. Arguably we should do the same for `EncodingError` and `DecodingError` as well, since we don't do anything special for those errors (not anymore, anyway; we did a long time ago, before they had built-in descriptions of their own). This also leaves us no longer adding "special" handling for any error types except our own custom ones, which is in keeping with (if not strictly a case of obedience to) the general rule to only extend other frameworks' types with one's own protocols).

Honestly, the entire thing is a bit ridiculous in modern Swift (though it made sense in the 4.2 days). No one, in my experience, actually uses `DebuggableError` (certainly Vapor itself doesn't), nor `AbortError` for that matter (aside from the obvious sole purview of `Abort` itself).

Code after:
        let source: ErrorSource?
        let reason: String
        let level: Logger.Level
        switch error {
        case let debuggable as DebuggableError:
            if self.logLevel <= .trace {
                reason = debuggable.debuggableHelp(format: .long)
            } else {
                reason = debuggable.debuggableHelp(format: .short)
            }
            source = debuggable.source
            level = debuggable.logLevel
        case let abort as AbortError:
            reason = abort.reason
            source = nil
            level = .warning
        default:
            reason = String(reflecting: error)
            source = nil
            level = .warning
        }

        self.log(
            level: level,
            .init(stringLiteral: reason),
            file: source?.file ?? file,
            function: source?.function ?? function,
            line: numericCast(source?.line ?? line)
        )
    }
}