final void failAndReset(Throwable cause) {
        if (failed) {
            return;
        }

        if (cause instanceof WriteTimeoutException) {
            final HttpSession session = HttpSession.get(ch);
            // Mark the session as unhealthy so that subsequent requests do not use it.
            session.markUnacquirable();
        }

        if (cause instanceof ResponseCompleteException) {
            // - ResponseCompleteException means the response is successfully received.
            state = State.DONE;
            cancel();
            logBuilder.endRequest(cause);
        } else {
            fail(cause);
        }

        final Http2Error error;
        if (cause instanceof ResponseCompleteException || Exceptions.isStreamCancelling(cause)) {
            error = Http2Error.CANCEL;
        } else {
            error = Http2Error.INTERNAL_ERROR;
        }

        if (error.code() != Http2Error.CANCEL.code() && cause != ctx.cancellationCause()) {
            Exceptions.logIfUnexpected(logger, ch,
                                       HttpSession.get(ch).protocol(),
                                       "a request publisher raised an exception", cause);
        }

        if (ch.isActive()) {
            encoder.writeReset(id, streamId(), error);
            ch.flush();
        }
    }
Writes the {@link HttpHeaders trailers} to the {@link Channel}.
Note that the written data is not flushed by this method. The caller should explicitly call
{@link Channel#flush()} when each write unit is done.
core/src/main/java/com/linecorp/armeria/client/AbstractHttpRequestHandler.java