Repository: vapor/vapor
File: Sources/Vapor/HTTP/Server/HTTPServerHandler.swift (Swift)

Code before:
        case .success(let response):
            if request.method == .HEAD {
                response.forHeadRequest = true
            }
            self.serialize(response, for: request, context: context)
        }
    }
    
    func serialize(_ response: Response, for request: Request, context: ChannelHandlerContext) {
        switch request.version.major {
        case 2:
            context.write(self.wrapOutboundOut(response), promise: nil)
        default:
            let keepAlive = !self.isShuttingDown && request.isKeepAlive
            if self.isShuttingDown {
                self.logger.debug("In-flight request has completed")
            }
            response.headers.add(name: .connection, value: keepAlive ? "keep-alive" : "close")
            let done = context.write(self.wrapOutboundOut(response))
            done.whenComplete { result in
                switch result {
                case .success:
                    if !keepAlive {
                        context.close(mode: .output, promise: nil)
                    }
                case .failure(ChannelError.ioOnClosedChannel):
                    if case .stream(let stream) = response.body.storage {
                        stream.callback(ErrorBodyStreamWriter(eventLoop: request.eventLoop, error: ChannelError.ioOnClosedChannel))
                    }
                case .failure(let error):
                    self.errorCaught(context: context, error: error)
                }
            }
        }
    }
    
    func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) {
        switch event {
        case is ChannelShouldQuiesceEvent:
            self.logger.trace("HTTP handler will no longer respect keep-alive")
            self.isShuttingDown = true
        default:
            self.logger.trace("Unhandled user event: \(event)")
        }
    }
}

struct ErrorBodyStreamWriter: BodyStreamWriter {
    var eventLoop: EventLoop
    var error: Error
    func write(_ result: BodyStreamResult, promise: EventLoopPromise<Void>?) {

Review comment (suggestion):
quick question: why only when `.ioOnClosedChannel`? I would've thought that this needs to be done on any write error. And even if there's no write error but the connection goes away we should notify the user, right?

CC @Lukasa 

Code after:
        case .success(let response):
            if request.method == .HEAD {
                response.forHeadRequest = true
            }
            self.serialize(response, for: request, context: context)
        }
    }
    
    func serialize(_ response: Response, for request: Request, context: ChannelHandlerContext) {
        switch request.version.major {
        case 2:
            context.write(self.wrapOutboundOut(response), promise: nil)
        default:
            let keepAlive = !self.isShuttingDown && request.isKeepAlive
            if self.isShuttingDown {
                self.logger.debug("In-flight request has completed")
            }
            response.headers.add(name: .connection, value: keepAlive ? "keep-alive" : "close")
            let done = context.write(self.wrapOutboundOut(response))
            done.whenComplete { result in
                switch result {
                case .success:
                    if !keepAlive {
                        context.close(mode: .output, promise: nil)
                    }
                case .failure(let error):
                    if case .stream(let stream) = response.body.storage {
                        stream.callback(ErrorBodyStreamWriter(eventLoop: request.eventLoop, error: error))
                    }
                    self.errorCaught(context: context, error: error)
                }
            }
        }
    }
    
    func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) {
        switch event {
        case is ChannelShouldQuiesceEvent:
            self.logger.trace("HTTP handler will no longer respect keep-alive")
            self.isShuttingDown = true
        default:
            self.logger.trace("Unhandled user event: \(event)")
        }
    }
}

struct ErrorBodyStreamWriter: BodyStreamWriter {
    var eventLoop: EventLoop
    var error: Error
    func write(_ result: BodyStreamResult, promise: EventLoopPromise<Void>?) {
        promise?.fail(error)