Skip to content

[BUG][Triple] Generated Triple unary handlers cannot use SetHeader/SetTrailer #3444

Description

@Alanxtl

Problem

triple_protocol.SetHeader and SetTrailer document a unary handler usage pattern, for example:

func (srv *Server) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) {
    if err := triple.SetHeader(ctx, http.Header{"hi": []string{"triple"}}); err != nil {
        return nil, err
    }
    if err := triple.SetTrailer(ctx, http.Header{"end": []string{"end"}}); err != nil {
        return nil, err
    }
    return &greet.GreetResponse{}, nil
}

However, the generated Triple unary server path currently passes a ctx that does not contain the internal handlerOutgoingKey{} connection value required by SetHeader / SetTrailer.

As a result, calling either API from a generated unary service implementation returns an error similar to:

triple: failed to fetch the connection from the context ...

Why this happens

The low-level unary handler in protocol/triple/triple_protocol/handler.go embeds incoming metadata into the context with newIncomingContext(ctx, conn.RequestHeader()), but it does not expose the handler connection through handlerOutgoingKey{} before invoking the user handler.

Then SetHeader / SetTrailer in protocol/triple/triple_protocol/header.go try to fetch:

ctx.Value(handlerOutgoingKey{}).(StreamingHandlerConn)

and fail.

For generated unary handlers, the generated method wrapper also only calls the business handler and wraps the returned business response with triple_protocol.NewResponse(res), so the application has no other generated-level response metadata hook.

Expected behavior

Generated Triple unary service implementations should be able to use triple.SetHeader(ctx, ...) and triple.SetTrailer(ctx, ...) as documented, and clients should be able to capture those values with client.WithResponseHeader / client.WithResponseTrailer.

Related context

Recent client-side work exposes unary response metadata capture through call options. That solves the client read side, but this server-side generated unary write path is still not usable with the documented API.

Metadata

Metadata

Assignees

Labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions