Swift Vapor:catchMap未被等待致错误未捕获的解决方法
Your issue boils down to nested futures not being flattened, which means errors from deliveryService.send never make it to your catchMap handler. Here's the breakdown:
When you use map on the render future, you’re returning another Future<Response> inside it. That turns your entire chain into a Future<Future<Response>> (a nested future). The outer catchMap only catches errors from the initial render call—any errors from send get trapped inside the inner future, which never gets properly awaited before the request returns.
The Fix: Use flatMap Instead of map
flatMap is built exactly for this scenario: it takes a future, runs an async operation that returns another future, and flattens the result into a single, linear future chain. This ensures all errors (from both render and send) flow through to your error handler.
Here's your corrected code:
return emailTemplate.render(emailData, on: req) .flatMap { message -> Future<Response> in let deliveryService = try req.make(EmailDeliveryService.self) return try deliveryService.send(message, on: req) } .catchMap { error in throw Abort(.internalServerError, reason: "Error sending email.") } .transform(to: savedObj)
Why This Works:
- Flattening the Future Chain:
flatMapreplaces the messy nestedFuture<Future<Response>>with a singleFuture<Response>, so every step in the async flow is part of one continuous chain. - Full Error Propagation: Now, if either
emailTemplate.renderfails ordeliveryService.sendfails, the error will be passed straight to thecatchMaphandler. This triggers yourAbortbefore the request completes, ensuring the client gets an internal server error instead of an incorrect success response. - Sync Error Handling: Even the
try req.make(...)call insideflatMapwill be converted into a failed future if it throws, so that error is also caught bycatchMap.
内容的提问来源于stack exchange,提问作者marked-down

