static void writeError(final Context context, final ResponseMessage responseMessage, final MessageSerializer<?> serializer) {
        try {
            final ChannelHandlerContext ctx = context.getChannelHandlerContext();
            final ByteBuf ByteBuf = context.getRequestState() == HttpGremlinEndpointHandler.RequestState.STREAMING
                    ? serializer.writeErrorFooter(responseMessage, ctx.alloc())
                    : serializer.serializeResponseAsBinary(responseMessage, ctx.alloc());

            context.setRequestState(HttpGremlinEndpointHandler.RequestState.ERROR);

            if (!ctx.channel().attr(StateKey.HTTP_RESPONSE_SENT).get()) {
                final HttpResponse responseHeader = new DefaultHttpResponse(HTTP_1_1, responseMessage.getStatus().getCode());
                responseHeader.headers().set(TRANSFER_ENCODING, CHUNKED); // Set this to make it "keep alive" eligible.
                responseHeader.headers().set(HttpHeaderNames.CONTENT_TYPE, ctx.channel().attr(StateKey.SERIALIZER).get().getValue0());
                ctx.writeAndFlush(responseHeader);
                ctx.channel().attr(StateKey.HTTP_RESPONSE_SENT).set(true);
            }

            ctx.writeAndFlush(new DefaultHttpContent(ByteBuf));

            sendTrailingHeaders(ctx, responseMessage.getStatus().getCode(), responseMessage.getStatus().getException());
        } catch (SerializationException se) {
            logger.warn("Unable to serialize ResponseMessage: {} ", responseMessage);
        }
    }
Writes and flushes a {@link ResponseMessage} that contains an error back to the client. Can be used to send
errors while streaming or when no response chunk has been sent. This serves as the end of a response.

@param context           The netty context.
@param responseMessage   The response to send back.
@param serializer        The serializer to use to serialize the error response.
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java