Nick Schaefer
Nick Schaefer•3mo ago

Request for better Swift Error Handling

As I've been setting up my app in Swift, I've been encountering this error:
Thread 3: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
Thread 3: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
In this internal Convex code:
func callForResult<T: Decodable>(
name: String, args: [String: ConvexEncodable?]? = nil, remoteCall: RemoteCall
)
async throws -> T
{
let rawResult = try await remoteCall(
name,
args?.mapValues({ v in
try v?.convexEncode() ?? "null"
}) ?? [:])
return try! JSONDecoder().decode(T.self, from: Data(rawResult.utf8)) // here
}
func callForResult<T: Decodable>(
name: String, args: [String: ConvexEncodable?]? = nil, remoteCall: RemoteCall
)
async throws -> T
{
let rawResult = try await remoteCall(
name,
args?.mapValues({ v in
try v?.convexEncode() ?? "null"
}) ?? [:])
return try! JSONDecoder().decode(T.self, from: Data(rawResult.utf8)) // here
}
At first I discovered it was because I was naming my Convex mutation name with a dot instead of a colon try await convex.mutation("~~items.create~~item:create", with: ["name": name]). But now I'm experiencing the same error for another completely different reason. Wrapping the mutation/action in a do/try/catch does not catch this error either - it crashes the app every time. I may follow this up with my latest issue if I don't solve it soon, but I would appreciate some better error handling here if possible. Thanks 🙂
4 Replies
Convex Bot
Convex Bot•3mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
jamwt
jamwt•3mo ago
dunno if @dowski has any guidance here, since he knows everything about these libraries
Nick Schaefer
Nick SchaeferOP•3mo ago
I think I may have found my culprit... My return value was in fact an object. I thought that code was checking the argument types. So the error was more useful than I thought, but still very confusing. So it seems that in Swift the return value from an action and mutation has to be a String. So I'll just be stringifying the data instead. If this helps anyone who finds this. Or if I'm wrong please let me know. Ok, I'm wrong. I missed this line:
The data from the remote function will be deserialized to your custom struct. Often your use of the type can be inferred from the calling context, and you can skip the yielding argument.
dowski
dowski•2mo ago
hey sorry for the delay responding here - i was away for the holidays and then busy with other stuff lately any ideas on what a better error would look like? it felt like a good place to assert b/c it feels like a developer error that should be solved before shipping, vs. something that should be able to be caught

Did you find this page helpful?