From 0c93460a8eadd2573c5f89c9e2635591a09d9c7a Mon Sep 17 00:00:00 2001 From: changhui lee Date: Mon, 5 Aug 2024 15:32:28 +0900 Subject: [PATCH] Handle panic during conversion to connectCode (#951) If an unhashable error is given, the error cannot be converted to a ConnectError with a map, causing a panic and shutting down the server. --------- Co-authored-by: Youngteac Hong --- server/rpc/connecthelper/status.go | 12 +++++++- server/rpc/connecthelper/status_test.go | 39 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 server/rpc/connecthelper/status_test.go diff --git a/server/rpc/connecthelper/status.go b/server/rpc/connecthelper/status.go index 2b330c70d..8708b401b 100644 --- a/server/rpc/connecthelper/status.go +++ b/server/rpc/connecthelper/status.go @@ -151,7 +151,17 @@ func errorToConnectError(err error) (*connect.Error, bool) { cause = errors.Unwrap(cause) } - connectCode, ok := errorToConnectCode[cause] + // NOTE(hackerwins): This prevents panic when the cause is an unhashable + // error. + var connectCode connect.Code + var ok bool + defer func() { + if r := recover(); r != nil { + ok = false + } + }() + + connectCode, ok = errorToConnectCode[cause] if !ok { return nil, false } diff --git a/server/rpc/connecthelper/status_test.go b/server/rpc/connecthelper/status_test.go new file mode 100644 index 000000000..aca1f4d57 --- /dev/null +++ b/server/rpc/connecthelper/status_test.go @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Yorkie Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package connecthelper + +import ( + "testing" + + "connectrpc.com/connect" + "github.com/stretchr/testify/assert" + "go.mongodb.org/mongo-driver/mongo" + + "github.com/yorkie-team/yorkie/api/converter" +) + +func TestStatus(t *testing.T) { + t.Run("errorToConnectCode test", func(t *testing.T) { + status, ok := errorToConnectError(converter.ErrPackRequired) + assert.True(t, ok) + assert.Equal(t, status.Code(), connect.CodeInvalidArgument) + + status, ok = errorToConnectError(mongo.CommandError{}) + assert.False(t, ok) + assert.Nil(t, status) + }) +}