do { try callThatCanThrow () } catch DecodingError . keyNotFound { // for error enums, this will match a specific case } catch DecodingError . keyNotFound ( let key , let c ) where key . stringValue == "test" { // for error enums, this will match a specific case, unwrap the payload, // and execute this block if the where condition is met } catch DecodingError . keyNotFound ( let key , let c ) { // for error enums, this will match a specific case // and unwrap the payload } catch let DecodingError . keyNotFound ( key , c ) { // for error enums, this will match a specific case // and unwrap the payload (alternative syntax) } catch is DecodingError { // catch all errors of type DecodingError, but don't bind it to a variable } catch let error as DecodingError { // catch all errors of type DecodingError, and bind it to `error` } catch let error as NSError { // catch all errors, but convert covert to NSError before binding // AFAIK, all errors can be implictly converted to NSError, // so this should always succeed } catch { // catch everything else, and implicitly bind it to a variable named `error` }