Skip to content

Update inconsistency error to be better suited to general use #408

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

Merged
merged 3 commits into from
May 19, 2025
Merged
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
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/CodableVendorExtendable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension CodableVendorExtendable {
let invalidKeys = extensions.keys.filter { !$0.lowercased().starts(with: "x-") }
if !invalidKeys.isEmpty {
let invalidKeysList = "[ " + invalidKeys.joined(separator: ", ") + " ]"
throw InconsistencyError(
throw GenericError(
subjectName: "Vendor Extension",
details: "Found at least one vendor extension property that does not begin with the required 'x-' prefix. Invalid properties: \(invalidKeysList)",
codingPath: decoder.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Components Object/Components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ extension OpenAPI.Components: Decodable {
vendorExtensions = try Self.extensions(from: decoder)
} catch let error as DecodingError {
if let underlyingError = error.underlyingError as? KeyDecodingError {
throw InconsistencyError(
throw GenericError(
subjectName: error.subjectName,
details: underlyingError.localizedDescription,
codingPath: error.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Content/Content.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ extension OpenAPI.Content: Decodable {
let container = try decoder.container(keyedBy: CodingKeys.self)

guard !(container.contains(.examples) && container.contains(.example)) else {
throw InconsistencyError(
throw GenericError(
subjectName: "Example and Examples",
details: "Only one of `example` and `examples` is allowed in the Media Type Object (`OpenAPI.Content`).",
codingPath: container.codingPath
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIKit/Document/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ extension OpenAPI.Document: Decodable {
} catch let error as OpenAPI.Error.Decoding.Path {

throw OpenAPI.Error.Decoding.Document(error)
} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Document(error)
} catch let error as DecodingError {
Expand Down Expand Up @@ -679,7 +679,7 @@ internal func decodeSecurityRequirements<CodingKeys: CodingKey>(from container:
return (try? components.contains(ref)) ?? false
}
guard securityKeysAndValues.map({ $0.key }).allSatisfy(foundInComponents) else {
throw InconsistencyError(
throw GenericError(
subjectName: key.stringValue,
details: "Each key found in a Security Requirement dictionary must refer to a Security Scheme present in the Components dictionary",
codingPath: container.codingPath + [key]
Expand Down Expand Up @@ -728,7 +728,7 @@ internal func validate(securityRequirements: [OpenAPI.SecurityRequirement], at p
]
.map(AnyCodingKey.init(stringValue:))

throw InconsistencyError(
throw GenericError(
subjectName: schemeKey,
details: "Each key found in a Security Requirement dictionary must refer to a Security Scheme present in the Components dictionary",
codingPath: keys
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension OpenAPI.Error.Decoding {

public enum Context: Sendable {
case path(Path)
case inconsistency(InconsistencyError)
case inconsistency(GenericError)
case other(Swift.DecodingError)
case neither(EitherDecodeNoTypesMatchedError)
}
Expand Down Expand Up @@ -82,7 +82,7 @@ extension OpenAPI.Error.Decoding.Document {
codingPath = error.codingPath
}

internal init(_ error: InconsistencyError) {
internal init(_ error: GenericError) {
context = .inconsistency(error)
codingPath = error.codingPath
}
Expand All @@ -107,7 +107,7 @@ extension OpenAPI.Error.Decoding.Document: DiggingError {
public init(unwrapping error: Swift.DecodingError) {
if let decodingError = error.underlyingError as? Swift.DecodingError {
self = Self(unwrapping: decodingError)
} else if let inconsistencyError = error.underlyingError as? InconsistencyError {
} else if let inconsistencyError = error.underlyingError as? GenericError {
self = Self(inconsistencyError)
} else if let pathError = error.underlyingError as? OpenAPI.Error.Decoding.Path {
self = Self(pathError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension OpenAPI.Error.Decoding {
public enum Context: Sendable {
case request(Request)
case response(Response)
case inconsistency(InconsistencyError)
case inconsistency(GenericError)
case other(Swift.DecodingError)
case neither(EitherDecodeNoTypesMatchedError)
}
Expand Down Expand Up @@ -95,7 +95,7 @@ extension OpenAPI.Error.Decoding.Operation {
relativeCodingPath = Array(codingPath)
}

internal init(_ error: InconsistencyError) {
internal init(_ error: GenericError) {
var codingPath = error.codingPath.dropFirst(2)
// this part of the coding path is structurally guaranteed to be an HTTP verb.
let verb = OpenAPI.HttpMethod(rawValue: codingPath.removeFirst().stringValue.uppercased())!
Expand Down Expand Up @@ -139,7 +139,7 @@ extension OpenAPI.Error.Decoding.Operation: DiggingError {
self = Self(responseError)
} else if let responseError = error.underlyingError as? OpenAPI.Error.Decoding.Response {
self = Self(responseError)
} else if let inconsistencyError = error.underlyingError as? InconsistencyError {
} else if let inconsistencyError = error.underlyingError as? GenericError {
self = Self(inconsistencyError)
} else if let eitherError = error.underlyingError as? EitherDecodeNoTypesMatchedError {
self = Self(eitherError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension OpenAPI.Error.Decoding {

public enum Context: Sendable {
case endpoint(Operation)
case inconsistency(InconsistencyError)
case inconsistency(GenericError)
case other(Swift.DecodingError)
case neither(EitherDecodeNoTypesMatchedError)
}
Expand Down Expand Up @@ -120,7 +120,7 @@ extension OpenAPI.Error.Decoding.Path {
relativeCodingPath = Array(codingPath)
}

internal init(_ error: InconsistencyError) {
internal init(_ error: GenericError) {
var codingPath = error.codingPath.dropFirst()
let route = OpenAPI.Path(rawValue: codingPath.removeFirst().stringValue)

Expand Down Expand Up @@ -165,7 +165,7 @@ extension OpenAPI.Error.Decoding.Path {
// public init(unwrapping error: Swift.DecodingError) {
// if let decodingError = error.underlyingError as? Swift.DecodingError {
// self = Self(unwrapping: decodingError)
// } else if let inconsistencyError = error.underlyingError as? InconsistencyError {
// } else if let inconsistencyError = error.underlyingError as? GenericError {
// self = Self(inconsistencyError)
// } else if let eitherError = error.underlyingError as? EitherDecodeNoTypesMatchedError {
// self = Self(eitherError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension OpenAPI.Error.Decoding {
internal let relativeCodingPath: [CodingKey]

public enum Context: Sendable {
case inconsistency(InconsistencyError)
case inconsistency(GenericError)
case other(Swift.DecodingError)
case neither(EitherDecodeNoTypesMatchedError)
}
Expand Down Expand Up @@ -68,7 +68,7 @@ extension OpenAPI.Error.Decoding.Response {
return Array(path.dropFirst(responsesIndex.advanced(by: 1)))
}

internal init(_ error: InconsistencyError) {
internal init(_ error: GenericError) {
var codingPath = Self.relativePath(from: error.codingPath)
let code = codingPath.removeFirst().stringValue.lowercased()

Expand Down Expand Up @@ -114,7 +114,7 @@ extension OpenAPI.Error.Decoding.Response: DiggingError {
public init(unwrapping error: Swift.DecodingError) {
if let decodingError = error.underlyingError as? Swift.DecodingError {
self = Self(unwrapping: decodingError)
} else if let inconsistencyError = error.underlyingError as? InconsistencyError {
} else if let inconsistencyError = error.underlyingError as? GenericError {
self = Self(inconsistencyError)
} else if let eitherError = error.underlyingError as? EitherDecodeNoTypesMatchedError {
self = Self(eitherError)
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ extension OpenAPI.Example: Decodable {
let container = try decoder.container(keyedBy: CodingKeys.self)

guard !(container.contains(.externalValue) && container.contains(.value)) else {
throw InconsistencyError(
throw GenericError(
subjectName: "example value",
details: "Found both `value` and `externalValue` keys in an Example. You must specify one or the other.",
codingPath: container.codingPath
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenAPIKit/Header/Header.swift
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,13 @@ extension OpenAPI.Header: Decodable {
case (nil, let schema?):
schemaOrContent = .init(schema)
case (nil, nil):
throw InconsistencyError(
throw GenericError(
subjectName: "Header",
details: "A header parameter must specify either `content` or `schema`",
codingPath: decoder.codingPath
)
case (_, _):
throw InconsistencyError(
throw GenericError(
subjectName: "Header",
details: "A header must specify one but not both `content` and `schema`",
codingPath: decoder.codingPath
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenAPIKit/JSONReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ extension JSONReference: Decodable {

if referenceString.first == "#" {
guard let internalReference = InternalReference(rawValue: referenceString) else {
throw InconsistencyError(
throw GenericError(
subjectName: "JSON Reference",
details: "Failed to parse a JSON Reference from '\(referenceString)'",
codingPath: container.codingPath
Expand All @@ -482,7 +482,7 @@ extension JSONReference: Decodable {
externalReference = URL(string: referenceString)
#endif
guard let externalReference else {
throw InconsistencyError(
throw GenericError(
subjectName: "JSON Reference",
details: "Failed to parse a valid URI for a JSON Reference from '\(referenceString)'",
codingPath: container.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Operation/Operation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ extension OpenAPI.Operation: Decodable {
} catch let error as DecodingError {

throw OpenAPI.Error.Decoding.Operation(unwrapping: error)
} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Operation(error)
} catch let error as EitherDecodeNoTypesMatchedError {
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIKit/Parameter/Parameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ extension OpenAPI.Parameter: Decodable {
context = .header(required: required)
case .path:
if !required {
throw InconsistencyError(
throw GenericError(
subjectName: name,
details: "positional path parameters must be explicitly set to required",
codingPath: decoder.codingPath
Expand All @@ -324,13 +324,13 @@ extension OpenAPI.Parameter: Decodable {
case (nil, let schema?):
schemaOrContent = .init(schema)
case (nil, nil):
throw InconsistencyError(
throw GenericError(
subjectName: name,
details: "A parameter must specify either `content` or `schema`",
codingPath: decoder.codingPath
)
case (_, _):
throw InconsistencyError(
throw GenericError(
subjectName: name,
details: "A parameter must specify one but not both `content` and `schema`",
codingPath: decoder.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Path Item/PathItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ extension OpenAPI.PathItem: Decodable {
} catch let error as DecodingError {

throw OpenAPI.Error.Decoding.Path(error)
} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Path(error)
} catch let error as OpenAPI.Error.Decoding.Operation {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Request/Request.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ extension OpenAPI.Request: Decodable {
required = try container.decodeIfPresent(Bool.self, forKey: .required) ?? false

vendorExtensions = try Self.extensions(from: decoder)
} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Request(error)
} catch let error as Swift.DecodingError {
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit/Response/Response.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ extension OpenAPI.Response: Decodable {

vendorExtensions = try Self.extensions(from: decoder)

} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Response(error)
} catch let error as EitherDecodeNoTypesMatchedError {
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIKit/Schema Object/JSONSchema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ extension JSONSchema: Decodable {
if keysFrom.count > 1 {
_warnings.append(
.underlyingError(
InconsistencyError(
GenericError(
subjectName: "Schema",
details: "A schema contains properties for multiple types of schemas, namely: \(keysFrom).",
codingPath: decoder.codingPath
Expand All @@ -2066,7 +2066,7 @@ extension JSONSchema: Decodable {
if !keysFromElsewhere.isEmpty {
_warnings.append(
.underlyingError(
InconsistencyError(
GenericError(
subjectName: "OpenAPI Schema",
details: "Found schema attributes not consistent with the type specified: \(typeHint). Specifically, attributes for these other types: \(keysFromElsewhere)",
codingPath: decoder.codingPath
Expand Down Expand Up @@ -2124,7 +2124,7 @@ extension JSONSchema: Decodable {
if fragmentContext.isEmpty && hintContainerCount > 0 {
_warnings.append(
.underlyingError(
InconsistencyError(
GenericError(
subjectName: "OpenAPI Schema",
details: "Found nothing but unsupported attributes.",
codingPath: decoder.codingPath
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIKit/Schema Object/JSONSchemaContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ extension JSONSchema.CoreContext: Decodable {
case (true, false):
_permissions = .readOnly
case (true, true):
throw InconsistencyError(
throw GenericError(
subjectName: "JSONSchema",
details: "Either `readOnly` or `writeOnly` can be true but not both",
codingPath: decoder.codingPath
Expand Down Expand Up @@ -1033,7 +1033,7 @@ extension JSONSchema.CoreContext: Decodable {
nullable = _nullable
warnings.append(
.underlyingError(
InconsistencyError(
GenericError(
subjectName: "OpenAPI Schema",
details: "Found 'nullable' property. This property is not supported by OpenAPI v3.1.x. OpenAPIKit has translated it into 'type: [\"null\", ...]'.",
codingPath: container.codingPath
Expand Down Expand Up @@ -1167,7 +1167,7 @@ extension JSONSchema.IntegerContext: Decodable {
let value = try intAttempt
?? doubleAttempt.map { floatVal in
guard let integer = Int(exactly: floatVal) else {
throw InconsistencyError(
throw GenericError(
subjectName: max ? "maximum" : "minimum",
details: "Expected an Integer literal but found a floating point value (\(String(describing: floatVal)))",
codingPath: decoder.codingPath,
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenAPIKit/Utility/Container+DecodeURLAsString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension KeyedDecodingContainerProtocol {
url = URL(string: string)
#endif
guard let url else {
throw InconsistencyError(
throw GenericError(
subjectName: key.stringValue,
details: "If specified, must be a valid URL",
codingPath: codingPath
Expand All @@ -51,7 +51,7 @@ extension KeyedDecodingContainerProtocol {
url = URL(string: string)
#endif
guard let url else {
throw InconsistencyError(
throw GenericError(
subjectName: key.stringValue,
details: "If specified, must be a valid URL",
codingPath: codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit30/CodableVendorExtendable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension CodableVendorExtendable {
let invalidKeys = extensions.keys.filter { !$0.lowercased().starts(with: "x-") }
if !invalidKeys.isEmpty {
let invalidKeysList = "[ " + invalidKeys.joined(separator: ", ") + " ]"
throw InconsistencyError(
throw GenericError(
subjectName: "Vendor Extension",
details: "Found at least one vendor extension property that does not begin with the required 'x-' prefix. Invalid properties: \(invalidKeysList)",
codingPath: decoder.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit30/Components Object/Components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ extension OpenAPI.Components: Decodable {
vendorExtensions = try Self.extensions(from: decoder)
} catch let error as DecodingError {
if let underlyingError = error.underlyingError as? KeyDecodingError {
throw InconsistencyError(
throw GenericError(
subjectName: error.subjectName,
details: underlyingError.localizedDescription,
codingPath: error.codingPath
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIKit30/Content/Content.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ extension OpenAPI.Content: Decodable {
let container = try decoder.container(keyedBy: CodingKeys.self)

guard !(container.contains(.examples) && container.contains(.example)) else {
throw InconsistencyError(
throw GenericError(
subjectName: "Example and Examples",
details: "Only one of `example` and `examples` is allowed in the Media Type Object (`OpenAPI.Content`).",
codingPath: container.codingPath
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIKit30/Document/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ extension OpenAPI.Document: Decodable {
} catch let error as OpenAPI.Error.Decoding.Path {

throw OpenAPI.Error.Decoding.Document(error)
} catch let error as InconsistencyError {
} catch let error as GenericError {

throw OpenAPI.Error.Decoding.Document(error)
} catch let error as DecodingError {
Expand Down Expand Up @@ -651,7 +651,7 @@ internal func decodeSecurityRequirements<CodingKeys: CodingKey>(from container:
return (try? components.contains(ref)) ?? false
}
guard securityKeysAndValues.map({ $0.key }).allSatisfy(foundInComponents) else {
throw InconsistencyError(
throw GenericError(
subjectName: key.stringValue,
details: "Each key found in a Security Requirement dictionary must refer to a Security Scheme present in the Components dictionary",
codingPath: container.codingPath + [key]
Expand Down Expand Up @@ -700,7 +700,7 @@ internal func validate(securityRequirements: [OpenAPI.SecurityRequirement], at p
]
.map(AnyCodingKey.init(stringValue:))

throw InconsistencyError(
throw GenericError(
subjectName: schemeKey,
details: "Each key found in a Security Requirement dictionary must refer to a Security Scheme present in the Components dictionary",
codingPath: keys
Expand Down
Loading