在Go中配置gRPC状态码及客户端逻辑:无效CameraID报错排查
gRPC状态码配置与客户端错误处理修复
问题现象
当传入无效CameraID时,客户端未收到预期的NotFound状态码,反而收到ConnectError,错误信息为missing trailer,错误码为2(对应Code.Unknown)。正常请求可正常工作。
代码问题分析
服务端Go代码问题
- 错误匹配逻辑错误:
服务端使用errors.Is(err, errors.New("camera not found"))匹配错误,但每次调用errors.New都会生成全新的error实例,errors.Is永远无法匹配成功,导致所有数据库错误都会返回codes.Internal状态码。 - 潜在响应干扰:
使用fmt.Println输出错误日志可能干扰gRPC响应的正常发送(虽然概率较低,但建议使用标准log包替代)。
客户端TypeScript代码
客户端的错误处理逻辑本身没问题,但由于服务端未正确返回预期的状态码,导致进入默认分支或无法匹配到NotFound。
修复步骤
1. 修正服务端错误匹配逻辑
定义全局错误变量,确保错误实例唯一:
package yourpackage import ( "errors" "log" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // 定义全局错误变量,用于相机不存在的场景 var ErrCameraNotFound = errors.New("camera not found") // GetCameraApplications gRPC handler func (s *yourService) GetCameraApplications(ctx context.Context, in *YourRequestType) (*GetCameraApplicationsResponse, error) { camera, err := db.ClientDB.GetCamera(ctx, in.CameraId) if err != nil { log.Printf("failed to get camera: %v", err) // 使用log替代fmt,避免干扰响应 if errors.Is(err, ErrCameraNotFound) { return nil, status.Error(codes.NotFound, "Camera not found") } return nil, status.Error(codes.Internal, "Problem getting camera apps") } // 正常业务逻辑... return &GetCameraApplicationsResponse{/* 填充响应数据 */}, nil }
2. 确保数据库层返回正确的错误
修改db.ClientDB.GetCamera方法,当相机不存在时,返回全局的ErrCameraNotFound,而非临时创建的错误:
func (db *ClientDB) GetCamera(ctx context.Context, cameraID string) (*Camera, error) { // 查询数据库逻辑... if camera == nil { return nil, ErrCameraNotFound // 返回全局错误变量 } // 其他错误场景返回对应错误... }
3. 检查gRPC服务端配置
确保服务端没有自定义拦截器错误拦截错误,或未正确传递gRPC状态错误。例如,若使用拦截器,需确保错误被透传:
func yourInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { resp, err := handler(ctx, req) // 不要修改或拦截正常的gRPC status错误 return resp, err }
验证
修改完成后,传入无效CameraID:
- 服务端会返回
codes.NotFound状态码及对应消息 - 客户端会捕获到
ConnectError且error.code为Code.NotFound(对应数值5),进而抛出"Camera not found"错误,不再出现missing trailer异常。
内容的提问来源于stack exchange,提问作者akanchha kumari
相关产品推荐
相关产品推荐

