public static HttpHeaders statusToTrailers(
            ServiceRequestContext ctx, HttpHeadersBuilder trailersBuilder,
            Status status, @Nullable Metadata metadata) {
        try {
            MetadataUtil.fillHeaders(metadata, trailersBuilder);
        } catch (Exception e) {
            // A buggy user-implemented custom metadata serializer may throw
            // an exception. Leave a log message and set the INTERNAL status.
            logger.warn("{} Failed to serialize metadata; overriding the original status ({}) with INTERNAL:",
                        ctx, status, e);
            return trailersBuilder
                    .set(GrpcHeaderNames.GRPC_STATUS, GRPC_STATUS_CODE_INTERNAL)
                    .build();
        }
        GrpcTrailersUtil.addStatusMessageToTrailers(
                trailersBuilder, status.getCode().value(), status.getDescription(), null);

        if (ctx.config().verboseResponses() && status.getCause() != null) {
            final ThrowableProto proto = GrpcStatus.serializeThrowable(status.getCause());
            trailersBuilder.add(GrpcHeaderNames.ARMERIA_GRPC_THROWABLEPROTO_BIN,
                                Base64.getEncoder().encodeToString(proto.toByteArray()));
        }

        final HttpHeaders additionalTrailers = ctx.additionalResponseTrailers();
        ctx.mutateAdditionalResponseTrailers(HttpHeadersBuilder::clear);
        trailersBuilder.add(additionalTrailers);
        return trailersBuilder.build();
    }
Cancels a call when the call was closed by a client, not by server.
grpc/src/main/java/com/linecorp/armeria/internal/server/grpc/AbstractServerCall.java