-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from mattpolzin/improve-parsing-errors
Improve Parsing Errors
- Loading branch information
Showing
38 changed files
with
2,153 additions
and
119 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
116 changes: 116 additions & 0 deletions
116
Sources/OpenAPIKit/Decoding Errors/DecodingErrorExtensions.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// | ||
// DecodingErrorExtensions.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 2/26/20. | ||
// | ||
|
||
import Foundation | ||
|
||
internal extension Swift.DecodingError { | ||
var subjectName: String { | ||
let name: String? = { | ||
switch self { | ||
case .keyNotFound(let key, _): | ||
return "\(key.stringValue)" | ||
case .typeMismatch(_, let ctx), .valueNotFound(_, let ctx), .dataCorrupted(let ctx): | ||
return ctx.codingPath.last?.stringValue | ||
@unknown default: | ||
return nil | ||
} | ||
}() | ||
|
||
return name ?? "[unknown object]" | ||
} | ||
|
||
var codingPathWithoutSubject: [CodingKey] { | ||
switch self { | ||
case .keyNotFound(_, let ctx): | ||
return ctx.codingPath | ||
case .typeMismatch(_, let ctx), .valueNotFound(_, let ctx), .dataCorrupted(let ctx): | ||
return ctx.codingPath.count > 0 ? ctx.codingPath.dropLast() : [] | ||
@unknown default: | ||
return [] | ||
} | ||
} | ||
|
||
var codingPath: [CodingKey] { | ||
switch self { | ||
case .keyNotFound(_, let ctx), .typeMismatch(_, let ctx), .valueNotFound(_, let ctx), .dataCorrupted(let ctx): | ||
return ctx.codingPath | ||
@unknown default: | ||
return [] | ||
} | ||
} | ||
|
||
var relativeCodingPathString: String { | ||
return codingPathWithoutSubject.stringValue | ||
} | ||
|
||
var errorCategory: ErrorCategory { | ||
switch self { | ||
case .typeMismatch(let type, _): | ||
return .typeMismatch(expectedTypeName: String(describing: type)) | ||
case .valueNotFound: | ||
return .missing(.value) | ||
case .keyNotFound: | ||
return .missing(.key) | ||
case .dataCorrupted: | ||
return .dataCorrupted(underlying: underlyingError) | ||
@unknown default: | ||
return .dataCorrupted(underlying: underlyingError) | ||
} | ||
} | ||
|
||
var underlyingError: Swift.Error? { | ||
switch self { | ||
case .typeMismatch(_, let ctx), .valueNotFound(_, let ctx), .keyNotFound(_, let ctx), .dataCorrupted(let ctx): | ||
return ctx.underlyingError | ||
@unknown default: | ||
return nil | ||
} | ||
} | ||
|
||
func replacingPath(with codingPath: [CodingKey]) -> Self { | ||
switch self { | ||
case .typeMismatch(let type, let ctx): | ||
return .typeMismatch(type, ctx.replacingPath(with: codingPath)) | ||
case .valueNotFound(let type, let ctx): | ||
return .valueNotFound(type, ctx.replacingPath(with: codingPath)) | ||
case .keyNotFound(let key, let ctx): | ||
return .keyNotFound(key, ctx.replacingPath(with: codingPath)) | ||
case .dataCorrupted(let ctx): | ||
return .dataCorrupted(ctx.replacingPath(with: codingPath)) | ||
@unknown default: | ||
return .dataCorrupted(.init(codingPath: codingPath, debugDescription: "unknown error")) | ||
} | ||
} | ||
} | ||
|
||
internal extension Swift.DecodingError.Context { | ||
func replacingPath(with codingPath: [CodingKey]) -> Self { | ||
return Swift.DecodingError.Context( | ||
codingPath: codingPath, | ||
debugDescription: debugDescription, | ||
underlyingError: underlyingError | ||
) | ||
} | ||
} | ||
|
||
internal struct DecodingErrorWrapper: OpenAPIError { | ||
let decodingError: Swift.DecodingError | ||
|
||
var subjectName: String { decodingError.subjectName } | ||
|
||
var contextString: String { | ||
let relativeCodingPathString = decodingError.relativeCodingPathString | ||
|
||
return relativeCodingPathString.isEmpty | ||
? "" | ||
: "in \(relativeCodingPathString)" | ||
} | ||
|
||
var errorCategory: ErrorCategory { decodingError.errorCategory } | ||
|
||
var codingPath: [CodingKey] { decodingError.codingPath } | ||
} |
84 changes: 84 additions & 0 deletions
84
Sources/OpenAPIKit/Decoding Errors/DocumentDecodingError.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 2/23/20. | ||
// | ||
|
||
import Foundation | ||
|
||
extension OpenAPI.Error.Decoding { | ||
public struct Document: OpenAPIError { | ||
public let context: Context | ||
public let codingPath: [CodingKey] | ||
|
||
public enum Context { | ||
case path(Path) | ||
case inconsistency(InconsistencyError) | ||
case generic(Swift.DecodingError) | ||
} | ||
} | ||
} | ||
|
||
extension OpenAPI.Error.Decoding.Document { | ||
public var subjectName: String { | ||
switch context { | ||
case .path(let pathError): | ||
return pathError.subjectName | ||
|
||
case .generic(let decodingError): | ||
return decodingError.subjectName | ||
|
||
case .inconsistency(let error): | ||
return error.subjectName | ||
} | ||
} | ||
|
||
public var contextString: String { | ||
switch context { | ||
case .path(let pathError): | ||
return pathError.contextString | ||
case .generic, .inconsistency: | ||
return relativeCodingPathString.isEmpty | ||
? "in the root Document object" | ||
: "in Document\(relativeCodingPathString)" | ||
} | ||
} | ||
|
||
public var errorCategory: ErrorCategory { | ||
switch context { | ||
case .path(let pathError): | ||
return pathError.errorCategory | ||
case .generic(let error): | ||
return error.errorCategory | ||
case .inconsistency(let error): | ||
return .inconsistency(details: error.details) | ||
} | ||
} | ||
|
||
internal var relativeCodingPathString: String { | ||
switch context { | ||
case .generic(let decodingError): | ||
return decodingError.relativeCodingPathString | ||
case .inconsistency: | ||
return "" | ||
case .path(let pathError): | ||
return pathError.relativeCodingPathString | ||
} | ||
} | ||
|
||
internal init(_ error: DecodingError) { | ||
context = .generic(error) | ||
codingPath = error.codingPath | ||
} | ||
|
||
internal init(_ error: InconsistencyError) { | ||
context = .inconsistency(error) | ||
codingPath = error.codingPath | ||
} | ||
|
||
internal init(_ error: OpenAPI.Error.Decoding.Path) { | ||
context = .path(error) | ||
codingPath = error.codingPath | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
Sources/OpenAPIKit/Decoding Errors/InconsistencyError.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// InconsistencyError.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 2/26/20. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct InconsistencyError: Swift.Error, OpenAPIError { | ||
public let subjectName: String | ||
public let details: String | ||
public let codingPath: [CodingKey] | ||
|
||
public var contextString: String { "" } | ||
public var errorCategory: ErrorCategory { .inconsistency(details: details) } | ||
|
||
public var localizedDescription: String { details } | ||
} |
Oops, something went wrong.