MCPcopy
hub / github.com/grpc/grpc-go / writeStatus

Method writeStatus

internal/transport/handler_server.go:228–288  ·  view source on GitHub ↗
(s *ServerStream, st *status.Status)

Source from the content-addressed store, hash-verified

226}
227
228func (ht *serverHandlerTransport) writeStatus(s *ServerStream, st *status.Status) error {
229 ht.writeStatusMu.Lock()
230 defer ht.writeStatusMu.Unlock()
231
232 headersWritten := s.updateHeaderSent()
233 err := ht.do(func() {
234 if !headersWritten {
235 ht.writePendingHeaders(s)
236 }
237
238 // And flush, in case no header or body has been sent yet.
239 // This forces a separation of headers and trailers if this is the
240 // first call (for example, in end2end tests's TestNoService).
241 ht.rw.(http.Flusher).Flush()
242
243 h := ht.rw.Header()
244 h.Set("Grpc-Status", fmt.Sprintf("%d", st.Code()))
245 if m := st.Message(); m != "" {
246 h.Set("Grpc-Message", encodeGrpcMessage(m))
247 }
248
249 s.hdrMu.Lock()
250 defer s.hdrMu.Unlock()
251 if p := st.Proto(); p != nil && len(p.Details) > 0 {
252 delete(s.trailer, grpcStatusDetailsBinHeader)
253 stBytes, err := proto.Marshal(p)
254 if err != nil {
255 // TODO: return error instead, when callers are able to handle it.
256 panic(err)
257 }
258
259 h.Set(grpcStatusDetailsBinHeader, encodeBinHeader(stBytes))
260 }
261
262 if len(s.trailer) > 0 {
263 for k, vv := range s.trailer {
264 // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
265 if isReservedHeader(k) {
266 continue
267 }
268 for _, v := range vv {
269 // http2 ResponseWriter mechanism to send undeclared Trailers after
270 // the headers have possibly been written.
271 h.Add(http2.TrailerPrefix+k, encodeMetadataHeader(k, v))
272 }
273 }
274 }
275 })
276
277 if err == nil && ht.stats != nil { // transport has not been closed
278 // Note: The trailer fields are compressed with hpack after this call returns.
279 // No WireLength field is set here.
280 s.hdrMu.Lock()
281 ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{
282 Trailer: s.trailer.Copy(),
283 })
284 s.hdrMu.Unlock()
285 }

Callers

nothing calls this directly

Calls 15

doMethod · 0.95
writePendingHeadersMethod · 0.95
CloseMethod · 0.95
encodeGrpcMessageFunction · 0.85
encodeBinHeaderFunction · 0.85
isReservedHeaderFunction · 0.85
encodeMetadataHeaderFunction · 0.85
updateHeaderSentMethod · 0.80
CodeMethod · 0.80
MessageMethod · 0.80
ProtoMethod · 0.80
CopyMethod · 0.80

Tested by

no test coverage detected