From aa9d403d09186b5b0cc9da3b322c1ba53c0f832a Mon Sep 17 00:00:00 2001 From: pablu Date: Wed, 5 Aug 2026 13:06:36 +0200 Subject: feat: create working client --- errors.go | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 errors.go (limited to 'errors.go') diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..d308853 --- /dev/null +++ b/errors.go @@ -0,0 +1,112 @@ +package zw + +import ( + "fmt" + + zwdaemonv1 "git.pablu.de/pablu/zw-go/gen/zwdaemon/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +const zwErrorDetailTypeURL = "type.googleapis.com/zw.daemon.v1.ZwErrorDetail" + +type ErrorCode = zwdaemonv1.ZwErrorCode + +const ( + ErrorCodeUnspecified = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_UNSPECIFIED + ErrorCodeVaultSealed = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_VAULT_SEALED + ErrorCodeVaultAlreadyUnsealed = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_VAULT_ALREADY_UNSEALED + ErrorCodeEntryNotFound = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_ENTRY_NOT_FOUND + ErrorCodeEntryAlreadyExists = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_ENTRY_ALREADY_EXISTS + ErrorCodeAuthenticationOrCorruption = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_AUTHENTICATION_OR_CORRUPTION + ErrorCodeInvalidVaultFormat = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_INVALID_VAULT_FORMAT + ErrorCodeUnsupportedVaultVersion = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_UNSUPPORTED_VAULT_VERSION + ErrorCodeUnsupportedProtocolVersion = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_UNSUPPORTED_PROTOCOL_VERSION + ErrorCodePermissionDenied = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_PERMISSION_DENIED + ErrorCodeStorageFull = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_STORAGE_FULL + ErrorCodeCommitFailed = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_COMMIT_FAILED + ErrorCodeInvalidRequest = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_INVALID_REQUEST + ErrorCodeInternal = zwdaemonv1.ZwErrorCode_ZW_ERROR_CODE_INTERNAL +) + +type RPCError struct { + GRPCCode codes.Code + ZwCode *ErrorCode + Message string + Retryable bool + + status *status.Status +} + +func (e *RPCError) Error() string { + return e.Message +} + +func (e *RPCError) GRPCStatus() *status.Status { + if e.status != nil { + return e.status + } + return status.New(e.GRPCCode, e.Message) +} + +type IncompatibleAPIVersionError struct { + ServerMajor uint32 + ServerMinor uint32 + SupportedMajor uint32 +} + +func (e *IncompatibleAPIVersionError) Error() string { + return fmt.Sprintf( + "daemon API version %d.%d is incompatible; this client supports major version %d", + e.ServerMajor, + e.ServerMinor, + e.SupportedMajor, + ) +} + +type UploadReadError struct { + Err error +} + +func (e *UploadReadError) Error() string { + return "read upload source: " + e.Err.Error() +} + +func (e *UploadReadError) Unwrap() error { + return e.Err +} + +func convertRPCError(err error) error { + if err == nil { + return nil + } + + grpcStatus, ok := status.FromError(err) + if !ok { + return err + } + + rpcErr := &RPCError{ + GRPCCode: grpcStatus.Code(), + Message: grpcStatus.Message(), + status: grpcStatus, + } + + for _, detail := range grpcStatus.Proto().GetDetails() { + if detail.GetTypeUrl() != zwErrorDetailTypeURL { + continue + } + + var zwDetail zwdaemonv1.ZwErrorDetail + if err := detail.UnmarshalTo(&zwDetail); err != nil { + continue + } + + code := zwDetail.GetCode() + rpcErr.ZwCode = &code + rpcErr.Retryable = zwDetail.GetRetryable() + break + } + + return rpcErr +} -- cgit 1.3.1