Skip to content

Instantly share code, notes, and snippets.

@emarashliev
Last active March 15, 2019 21:14
Show Gist options
  • Save emarashliev/820f37726cc02b38b04f306d8b1c0f2d to your computer and use it in GitHub Desktop.
Save emarashliev/820f37726cc02b38b04f306d8b1c0f2d to your computer and use it in GitHub Desktop.
Vapor Middleware that catches thrown errors and translate them. The preferred language should be passed by `Accept-Language` header
import NStack
import Vapor
import Sugar
protocol Translatable {
var translationKey: String { get }
}
extension AuthenticationError: Translatable {
var translationKey: String {
switch self {
case .signingError, .userNotFound, .weakPassword, .usernameAlreadyExists, .incorrectPassword:
return rawValue
default: return "GenericAuthenticationErrorKey"
}
}
}
struct TranslatedError: AbortError {
let identifier: String
let reason: String
let status: HTTPResponseStatus
}
public final class TranslateMiddleware: Middleware, ServiceType {
public static func makeService(for worker: Container) throws -> TranslateMiddleware {
return .default()
}
public static func `default`() -> TranslateMiddleware {
return .init()
}
public func respond(to req: Request, chainingTo next: Responder) throws -> Future<Response> {
let response: Future<Response>
do {
response = try next.respond(to: req)
} catch {
response = req.eventLoop.newFailedFuture(error: error)
}
return response.catchFlatMap { error in
guard let translatableError = error as? Translatable else {
throw error
}
let translationKey = translatableError.translationKey
let nstack: NStack = try req.make()
let language = req.http.headers.firstValue(name: .acceptLanguage)
let errorFuture = nstack.application.translate.get(
on: req,
platform: .backend,
language: language,
section: "errors",
key: translationKey
)
return errorFuture.map{ errorString in
switch error {
case let abortError as AbortError:
throw TranslatedError(
identifier: abortError.identifier,
reason: errorString,
status: abortError.status
)
default:
fatalError("You need to cover all the cases of translatable Errors")
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment