Skip to content

Commit

Permalink
Squashed 'apollo-ios-codegen/' changes from c341108e..2457cb65
Browse files Browse the repository at this point in the history
2457cb65 Codegen EntitySelectionTree + MergedSelections Refactor + Perf Improvments (#152)

git-subtree-dir: apollo-ios-codegen
git-subtree-split: 2457cb659273c7938a4a757f5676b216c5f4d720
  • Loading branch information
gh-action-runner authored and gh-action-runner committed Dec 20, 2023
1 parent 1874c20 commit 0175af0
Show file tree
Hide file tree
Showing 44 changed files with 1,632 additions and 1,201 deletions.
137 changes: 137 additions & 0 deletions Sources/ApolloCodegenLib/ApolloCodegen+Errors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import Foundation
import TemplateString
import OrderedCollections
import IR

extension ApolloCodegen {
/// Errors that can occur during code generation. These are fatal errors that prevent the code
/// generation from continuing execution.
public enum Error: Swift.Error, LocalizedError {
/// An error occured during validation of the GraphQL schema or operations.
case graphQLSourceValidationFailure(atLines: [String])
case testMocksInvalidSwiftPackageConfiguration
case inputSearchPathInvalid(path: String)
case schemaNameConflict(name: String)
case cannotLoadSchema
case cannotLoadOperations
case invalidConfiguration(message: String)
case invalidSchemaName(_ name: String, message: String)
case targetNameConflict(name: String)

public var errorDescription: String? {
switch self {
case let .graphQLSourceValidationFailure(lines):
return """
An error occured during validation of the GraphQL schema or operations! Check \(lines)
"""
case .testMocksInvalidSwiftPackageConfiguration:
return """
Schema Types must be generated with module type 'swiftPackageManager' to generate a \
swift package for test mocks.
"""
case let .inputSearchPathInvalid(path):
return """
Input search path '\(path)' is invalid. Input search paths must include a file \
extension component. (eg. '.graphql')
"""
case let .schemaNameConflict(name):
return """
Schema namespace '\(name)' conflicts with name of a type in the generated code. Please \
choose a different schema name. Suggestions: \(name)Schema, \(name)GraphQL, \(name)API.
"""
case .cannotLoadSchema:
return "A GraphQL schema could not be found. Please verify the schema search paths."
case .cannotLoadOperations:
return "No GraphQL operations could be found. Please verify the operation search paths."
case let .invalidConfiguration(message):
return "The codegen configuration has conflicting values: \(message)"
case let .invalidSchemaName(name, message):
return "The schema namespace `\(name)` is invalid: \(message)"
case let .targetNameConflict(name):
return """
Target name '\(name)' conflicts with a reserved library name. Please choose a different \
target name.
"""
}
}
}

/// Errors that may occur during code generation that are not fatal. If these errors are present,
/// the generated files will likely not compile correctly. Code generation execution can continue,
/// but these errors should be surfaced to the user.
public enum NonFatalError: Equatable {
case typeNameConflict(name: String, conflictingName: String, containingObject: String)

var errorTypeName: String {
switch self {
case .typeNameConflict(_, _, _):
return "TypeNameConflict"
}
}

public var failureReason: String {
switch self {
case let .typeNameConflict(name, conflictingName, containingObject):
return "Field '\(conflictingName)' conflicts with field '\(name)' in GraphQL definition `\(containingObject)`."
}
}

public var recoverySuggestion: String {
switch self {
case .typeNameConflict(_, _, _):
return """
It is recommended to use a field alias for one of these fields to resolve this conflict.
For more info see: https://www.apollographql.com/docs/ios/troubleshooting/codegen-troubleshooting#typenameconflict
"""
}
}

public var errorDescription: String? {
return "\(errorTypeName): \(failureReason)"
}

class Recorder {
var recordedErrors: [NonFatalError] = []

func record(error: NonFatalError) { recordedErrors.append(error) }
}
}

public struct NonFatalErrors: Swift.Error, LocalizedError {
public typealias FileName = String
public typealias ErrorsByFile = OrderedDictionary<FileName, [NonFatalError]>
public typealias DefinitionEntry = (FileName, [NonFatalError])

public internal(set) var errorsByFile: ErrorsByFile

init(
errorsByFile: ErrorsByFile = [:]
) {
self.errorsByFile = errorsByFile
}

mutating func merge(_ other: NonFatalErrors) {
errorsByFile.merge(other.errorsByFile) { _, new in new }
}

public var isEmpty: Bool { errorsByFile.isEmpty }

public var errorDescription: String? {
var recoverySuggestionsByErrorType: OrderedDictionary<String, String> = [:]

return TemplateString(
"""
\(errorsByFile.map {
"""
- \($0.key):
- \($0.value.compactMap {
recoverySuggestionsByErrorType[$0.errorTypeName] = $0.recoverySuggestion
return $0.errorDescription
})
"""
}, separator: "\n")
"""
).description
}
}
}

0 comments on commit 0175af0

Please sign in to comment.