From a3fac87cc6eac00e2499add923a679d3ee6f65d1 Mon Sep 17 00:00:00 2001 From: sundowndev <16480203+sundowndev@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:58:35 +0400 Subject: [PATCH] fix: http and rpc error codes --- gen/openapiv2/notes/v1/notes.swagger.json | 6 +++ proto/notes/v1/notes.pb.go | 54 +++++++++++++---------- proto/notes/v1/notes.proto | 10 +++++ server/notes.go | 8 ++-- server/notes_test.go | 4 +- 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/gen/openapiv2/notes/v1/notes.swagger.json b/gen/openapiv2/notes/v1/notes.swagger.json index 45726e6..1260dbb 100644 --- a/gen/openapiv2/notes/v1/notes.swagger.json +++ b/gen/openapiv2/notes/v1/notes.swagger.json @@ -66,6 +66,12 @@ "$ref": "#/definitions/v1EditNoteResponse" } }, + "404": { + "description": "Returned when the resource does not exist.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + }, "default": { "description": "An unexpected error response.", "schema": { diff --git a/proto/notes/v1/notes.pb.go b/proto/notes/v1/notes.pb.go index 9eb733d..e059c85 100644 --- a/proto/notes/v1/notes.pb.go +++ b/proto/notes/v1/notes.pb.go @@ -394,7 +394,7 @@ var file_notes_v1_notes_proto_rawDesc = []byte{ 0x10, 0x45, 0x64, 0x69, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x65, 0x52, - 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x32, 0xfb, 0x02, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x53, + 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x32, 0xcf, 0x03, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, @@ -408,33 +408,39 @@ var file_notes_v1_notes_proto_rawDesc = []byte{ 0x76, 0x69, 0x63, 0x65, 0x12, 0x08, 0x41, 0x64, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x1a, 0x0f, 0x41, 0x64, 0x64, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x08, 0x45, 0x64, 0x69, 0x74, + 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0xed, 0x01, 0x0a, 0x08, 0x45, 0x64, 0x69, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x4e, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x31, - 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x09, - 0x45, 0x64, 0x69, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x1a, 0x16, 0x45, 0x64, 0x69, 0x74, 0x20, - 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x74, 0x65, - 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x32, 0x17, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x65, 0x2e, - 0x69, 0x64, 0x7d, 0x42, 0xff, 0x01, 0x92, 0x41, 0x62, 0x12, 0x05, 0x32, 0x03, 0x31, 0x2e, 0x30, - 0x2a, 0x02, 0x01, 0x02, 0x72, 0x55, 0x0a, 0x23, 0x67, 0x52, 0x50, 0x43, 0x20, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2e, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x73, 0x75, 0x6e, 0x64, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x76, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, - 0x61, 0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, - 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x92, 0x41, + 0x83, 0x01, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x09, 0x45, 0x64, 0x69, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x1a, 0x16, 0x45, 0x64, 0x69, + 0x74, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, + 0x74, 0x65, 0x2e, 0x4a, 0x50, 0x0a, 0x03, 0x34, 0x30, 0x34, 0x12, 0x49, 0x0a, 0x2a, 0x52, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x2e, 0x12, 0x1b, 0x0a, 0x19, 0x1a, 0x17, 0x23, 0x2f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x32, 0x17, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x6e, + 0x6f, 0x74, 0x65, 0x2e, 0x69, 0x64, 0x7d, 0x42, 0xff, 0x01, 0x92, 0x41, 0x62, 0x12, 0x05, 0x32, + 0x03, 0x31, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x72, 0x55, 0x0a, 0x23, 0x67, 0x52, 0x50, 0x43, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x2e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x75, 0x6e, 0x64, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x76, 0x2f, 0x67, - 0x72, 0x70, 0x63, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x6e, - 0x6f, 0x74, 0x65, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4e, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x4e, - 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x5c, - 0x56, 0x31, 0xe2, 0x02, 0x14, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x4e, 0x6f, 0x74, 0x65, - 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x70, 0x63, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x0a, + 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x4e, + 0x6f, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x75, 0x6e, 0x64, 0x6f, 0x77, 0x6e, 0x64, + 0x65, 0x76, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, + 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4e, 0x58, 0x58, + 0xaa, 0x02, 0x08, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x4e, 0x6f, + 0x74, 0x65, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, + 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/proto/notes/v1/notes.proto b/proto/notes/v1/notes.proto index 5e17633..3643e42 100644 --- a/proto/notes/v1/notes.proto +++ b/proto/notes/v1/notes.proto @@ -37,6 +37,16 @@ service NotesService { summary: "Edit note" description: "Edit an existing note." tags: "NotesService" + responses: { + // Overwrites global definition. + key: "404"; + value: { + description: "Returned when the resource does not exist."; + schema: { + json_schema: {ref: "#/definitions/rpcStatus"} + } + } + } }; }; // rpc GetNote(GetNoteRequest) returns (GetNoteResponse) {}; diff --git a/server/notes.go b/server/notes.go index 8ce7fa0..7ac58be 100644 --- a/server/notes.go +++ b/server/notes.go @@ -6,6 +6,8 @@ import ( "github.com/bufbuild/protovalidate-go" "github.com/gofrs/uuid" notesv1 "github.com/sundowndev/grpc-api-example/proto/notes/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "sync" ) @@ -49,7 +51,7 @@ func (s *NotesService) AddNote(_ context.Context, req *notesv1.AddNoteRequest) ( } if err := s.validator.Validate(note); err != nil { - return nil, fmt.Errorf("validation failed: %v", err) + return nil, status.New(codes.InvalidArgument, err.Error()).Err() } s.notes = append(s.notes, note) @@ -68,7 +70,7 @@ func (s *NotesService) EditNote(_ context.Context, req *notesv1.EditNoteRequest) } if err := s.validator.Validate(editedNote); err != nil { - return nil, fmt.Errorf("validation failed: %v", err) + return nil, status.New(codes.InvalidArgument, err.Error()).Err() } var found bool @@ -81,7 +83,7 @@ func (s *NotesService) EditNote(_ context.Context, req *notesv1.EditNoteRequest) } if !found { - return nil, fmt.Errorf("couldn't find note with id: %s", req.Note.Id) + return nil, status.New(codes.NotFound, fmt.Sprintf("couldn't find note with id: %s", req.Note.Id)).Err() } return ¬esv1.EditNoteResponse{Note: editedNote}, nil diff --git a/server/notes_test.go b/server/notes_test.go index 5c0e8fa..fe51968 100644 --- a/server/notes_test.go +++ b/server/notes_test.go @@ -62,14 +62,14 @@ func TestNotesService_ListNotes(t *testing.T) { notes: []*notesv1.Note{ {Title: ""}, }, - wantErr: "validation failed: validation error:\n - title: value length must be at least 1 characters [string.min_len]", + wantErr: "validation error:\n - title: value length must be at least 1 characters [string.min_len]", }, { name: "test with max_len validation error", notes: []*notesv1.Note{ {Title: "this is a super long note title that can trigger a validation error"}, }, - wantErr: "validation failed: validation error:\n - title: value length must be at most 50 characters [string.max_len]", + wantErr: "validation error:\n - title: value length must be at most 50 characters [string.max_len]", }, }