From 4331d1826286d5512e0e8a0e95dfe1a76c2dbce5 Mon Sep 17 00:00:00 2001 From: Radek Gruchalski Date: Wed, 16 Feb 2022 09:06:06 +0100 Subject: [PATCH] Handle responseHeader.is_error. Closes #64 --- client/single_node_client.go | 14 ++++++++++++++ errors/client.go | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/client/single_node_client.go b/client/single_node_client.go index f658ed9..be55184 100644 --- a/client/single_node_client.go +++ b/client/single_node_client.go @@ -303,6 +303,20 @@ func (c *defaultSingleNodeClient) readResponseInto(reader *bytes.Buffer, m proto } } + if *responseHeader.IsError { + errorResponse := &ybApi.ErrorStatusPB{} + errorUnmarshalErr := utils.DeserializeProto(responsePayloadBuf, errorResponse) + if errorUnmarshalErr != nil { + return &errors.UnprocessableResponseError{ + Cause: errorUnmarshalErr, + ConsumedPayload: responseHeaderBuf, + } + } + return &errors.ServiceRPCError{ + Cause: errorResponse, + } + } + protoErr2 := utils.DeserializeProto(responsePayloadBuf, m) if protoErr2 != nil { return &errors.UnprocessableResponseError{ diff --git a/errors/client.go b/errors/client.go index 35d3c77..ae7dd18 100644 --- a/errors/client.go +++ b/errors/client.go @@ -38,6 +38,8 @@ const ( ErrorMessageReconnectRequired = "client: reconnect required" // ErrorMessageSendFailed is an error message. ErrorMessageSendFailed = "client: send failed" + // ErrorMessageServiceError is an error message. + ErrorMessageServiceError = "client: service error" // ErrorMessageUnprocessableResponse is an error message. ErrorMessageUnprocessableResponse = "client: unprocessable response" ) @@ -124,6 +126,25 @@ func (e *RequiresReconnectError) Error() string { return fmt.Sprintf("%s: no service for type '%s'", ErrorMessageReconnectRequired, e.Cause.Error()) } +// ServiceRPCError is returned when the client responds with +// a response header with is_error true. +type ServiceRPCError struct { + Cause *ybApi.ErrorStatusPB +} + +func (e *ServiceRPCError) Error() string { + codeString := ybApi.ErrorStatusPB_RpcErrorCodePB_name[int32(ybApi.ErrorStatusPB_FATAL_UNKNOWN)] + if e.Cause.Code != nil { + if v, ok := ybApi.ErrorStatusPB_RpcErrorCodePB_name[int32(*e.Cause.Code)]; ok { + codeString = v + } + } + if e.Cause.Message == nil { + return fmt.Sprintf("%s: %s", ErrorMessageServiceError, codeString) + } + return fmt.Sprintf("%s: %s: %s", ErrorMessageServiceError, codeString, *e.Cause.Message) +} + // SendError is returned when the client is unable to // send the payload or receive from the server. type SendError struct {