I am looking to create a function to handle potential errors in GraphQL mutation results, using the Apollo SDK. Apollo can have errors as part of its success data.
To keep it as generic as possible, I define my function as:
func alertResult(result: Result<GraphQLResult<Any>, Error>) {
print(result)
switch result {
case let .failure(error):
self.presentAlert(title: "Operation Error", message: "API says: \(error)")
case let .success(data):
if let errors = data.errors {
self.presentAlert(title: "Operation Error", message: "API says: \(errors)")
}
}
}
When used with a specific Apollo mutation, InviteToCommunityMutation
, the compiler rejects it with the following error:
Cannot convert value of type 'Result<GraphQLResult<InviteToCommunityMutation.Data>, any Error>' to expected argument type 'Result<GraphQLResult<Any>, any Error>'
I find this bizarre, as surely InviteToCommunityMutation.Data
should be convertible to Any
.
If I try to define my function more broadly with:
func alertResult(result: Result<Any, Error>)
then I get Type of expression is ambiguous without more context
when trying to extract data.errors
from .success(data)
.
Would love help! Also, I'm new to Stackoverflow, so tried to include only relevant data but happy to provide more.
CodePudding user response:
Make your function generic:
func alertResult<T>(result: Result<GraphQLResult<T>, Error>) {
By using T
as a generic placeholder type, you allow Swift to synthesize an appropriate function for any subtype of GraphQLResult
.
You can read about Swift Generics here.
Note: The error message tells you why Any
doesn’t work. Result<GraphQLResult<InviteToCommunityMutation.Data>, any Error>
and Result<GraphQLResult<Any>, any Error>
are two different types. Generics allow Swift to generate a function with the properly matching type.