Skip to content

Fix EncodingError/DecodingError bridging to NSError #10674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 3 additions & 53 deletions stdlib/public/SDK/Foundation/Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,9 @@
// Errors
//===----------------------------------------------------------------------===//

// Adding the following extensions to EncodingError and DecodingError allows them to bridge to NSErrors implicitly.

fileprivate let NSCodingPathErrorKey = "NSCodingPath"
fileprivate let NSDebugDescriptionErrorKey = "NSDebugDescription"

extension EncodingError : CustomNSError {
public static var errorDomain: String = NSCocoaErrorDomain

public var errorCode: Int {
switch self {
case .invalidValue(_, _): return CocoaError.coderInvalidValue.rawValue
}
}

public var errorUserInfo: [String : Any] {
let context: Context
switch self {
case .invalidValue(_, let c): context = c
}

return [NSCodingPathErrorKey: context.codingPath,
NSDebugDescriptionErrorKey: context.debugDescription]
}
}

extension DecodingError : CustomNSError {
public static var errorDomain: String = NSCocoaErrorDomain

public var errorCode: Int {
switch self {
case .valueNotFound(_, _): fallthrough
case .keyNotFound(_, _):
return CocoaError._coderValueNotFound.rawValue

case .typeMismatch(_, _): fallthrough
case .dataCorrupted(_):
return CocoaError._coderReadCorrupt.rawValue
}
}

public var errorUserInfo: [String : Any]? {
let context: Context
switch self {
case .typeMismatch(_, let c): context = c
case .valueNotFound(_, let c): context = c
case .keyNotFound(_, let c): context = c
case .dataCorrupted(let c): context = c
}

return [NSCodingPathErrorKey: context.codingPath,
NSDebugDescriptionErrorKey: context.debugDescription]
}
}
// Both of these error types bridge to NSError, and through the entry points they use, no further work is needed to make them localized.
extension EncodingError : LocalizedError {}
extension DecodingError : LocalizedError {}

//===----------------------------------------------------------------------===//
// Error Utilities
Expand Down
57 changes: 57 additions & 0 deletions stdlib/public/core/Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2040,6 +2040,31 @@ public enum EncodingError : Error {
///
/// Contains the attempted value, along with context for debugging.
case invalidValue(Any, Context)

// MARK: - Bridging

// CustomNSError bridging applies only when the CustomNSError conformance is applied in the same module as the declared error type.
// Since we cannot access CustomNSError (which is defined in Foundation) from here, we can use the "hidden" entry points.

public var _domain: String {
return "NSCocoaErrorDomain"
}

public var _code: Int {
switch self {
case .invalidValue(_, _): return 4866
}
}

public var _userInfo: AnyObject? {
let context: Context
switch self {
case .invalidValue(_, let c): context = c
}

return ["NSCodingPath": context.codingPath,
"NSDebugDescription": context.debugDescription] as AnyObject
}
}

/// An error that occurs during the decoding of a value.
Expand Down Expand Up @@ -2081,6 +2106,38 @@ public enum DecodingError : Error {
///
/// Contains context for debugging.
case dataCorrupted(Context)

// MARK: - Bridging

// CustomNSError bridging applies only when the CustomNSError conformance is applied in the same module as the declared error type.
// Since we cannot access CustomNSError (which is defined in Foundation) from here, we can use the "hidden" entry points.

public var _domain: String {
return "NSCocoaErrorDomain"
}

public var _code: Int {
switch self {
case .valueNotFound(_, _): fallthrough
case .keyNotFound(_, _): return 4865

case .typeMismatch(_, _): fallthrough
case .dataCorrupted(_): return 4864
}
}

public var _userInfo: AnyObject? {
let context: Context
switch self {
case .typeMismatch(_, let c): context = c
case .valueNotFound(_, let c): context = c
case .keyNotFound(_, let c): context = c
case .dataCorrupted(let c): context = c
}

return ["NSCodingPath": context.codingPath,
"NSDebugDescription": context.debugDescription] as AnyObject
}
}

//===----------------------------------------------------------------------===//
Expand Down