Browse Source

Middleware: Remove duplicate logic from ErrorMiddleware

master
Riyyi 1 month ago
parent
commit
56dcd4fb35
  1. 53
      Sources/App/Middleware/CustomErrorMiddleware.swift

53
Sources/App/Middleware/CustomErrorMiddleware.swift

@ -11,10 +11,18 @@ public final class CustomErrorMiddleware: Middleware {
public init(environment: Environment) { public init(environment: Environment) {
self.environment = environment self.environment = environment
self.errorMiddleware = ErrorMiddleware.`default`(environment: environment)
} }
public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> { public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
next.respond(to: request).flatMapErrorThrowing { error in
// Let ErrorMiddleware handle API endpoint errors
if let acceptHeader = request.headers.first(name: "Accept"),
acceptHeader == "application/json" {
return errorMiddleware.respond(to: request, chainingTo: next)
}
return next.respond(to: request).flatMapErrorThrowing { error in
self.makeResponse(with: request, reason: error) self.makeResponse(with: request, reason: error)
} }
} }
@ -47,45 +55,18 @@ public final class CustomErrorMiddleware: Middleware {
// Report the error // Report the error
req.logger.report(error: error, file: source.file, function: source.function, line: source.line) req.logger.report(error: error, file: source.file, function: source.function, line: source.line)
let body = makeResponseBody(with: req, reason: reason, status: status, headers: &headers) headers.contentType = .html
// Render error to a page
let statusCode = String(status.code)
let body = Response.Body(string: MainLayout(title: "Error \(statusCode))") {
ErrorPage(status: statusCode, reason: reason)
}.render())
// Create a Response with appropriate status // Create a Response with appropriate status
return Response(status: status, headers: headers, body: body) return Response(status: status, headers: headers, body: body)
} }
private func makeResponseBody(with req: Request, reason: String, status: HTTPResponseStatus,
headers: inout HTTPHeaders) -> Response.Body {
let body: Response.Body
if let acceptHeader = req.headers.first(name: "Accept"),
acceptHeader == "application/json" {
// Attempt to serialize the error to JSON
do {
let encoder = try ContentConfiguration.global.requireEncoder(for: .json)
var byteBuffer = req.byteBufferAllocator.buffer(capacity: 0)
try encoder.encode(ErrorResponse(error: true, reason: reason), to: &byteBuffer, headers: &headers)
body = .init(
buffer: byteBuffer,
byteBufferAllocator: req.byteBufferAllocator
)
} catch {
body = .init(string: "Oops: \(String(describing: error))\nWhile encoding error: \(reason)",
byteBufferAllocator: req.byteBufferAllocator)
headers.contentType = .plainText
}
}
else {
// Attempt to render the error to a page
let statusCode = String(status.code)
body = .init(string: MainLayout(title: "Error \(statusCode))") {
ErrorPage(status: statusCode, reason: reason)
}.render())
headers.contentType = .html
}
return body
}
private let environment: Environment private let environment: Environment
private let errorMiddleware: ErrorMiddleware
} }

Loading…
Cancel
Save