summaryrefslogtreecommitdiff
path: root/errors.go
diff options
context:
space:
mode:
authorpablu <me@pablu.de>2026-08-05 13:06:36 +0200
committerpablu <me@pablu.de>2026-08-05 16:11:59 +0200
commitaa9d403d09186b5b0cc9da3b322c1ba53c0f832a (patch)
tree02ce07ae0a15e01f3f03bb469ccc2cb9fede56cc /errors.go
parent67916c5d1c7001bab5bf08b6fec3a7f14ea4dd64 (diff)
feat: create working client
Diffstat (limited to 'errors.go')
-rw-r--r--errors.go112
1 files changed, 112 insertions, 0 deletions
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
+}