84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
package domain
|
|
|
|
import (
|
|
"fmt"
|
|
"unicode/utf8"
|
|
|
|
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
|
)
|
|
|
|
const MaxProtocolDetailBytes = 4 * 1024
|
|
|
|
// Error is the transport-neutral form of an RVBox structured failure.
|
|
type Error struct {
|
|
Code rvboxv1.ControlError_Code
|
|
Message string
|
|
Retryable bool
|
|
IssueUUID string
|
|
Cause error
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
if e.IssueUUID == "" {
|
|
return fmt.Sprintf("%s: %s", e.Code, e.Message)
|
|
}
|
|
return fmt.Sprintf("%s (%s): %s", e.Code, e.IssueUUID, e.Message)
|
|
}
|
|
|
|
func (e *Error) Unwrap() error { return e.Cause }
|
|
|
|
// NewError applies the stable retryability policy and bounds wire-visible text.
|
|
func NewError(code rvboxv1.ControlError_Code, message, issueUUID string) *Error {
|
|
return &Error{
|
|
Code: code,
|
|
Message: boundUTF8(message, MaxProtocolDetailBytes),
|
|
Retryable: DefaultRetryable(code),
|
|
IssueUUID: issueUUID,
|
|
}
|
|
}
|
|
|
|
func (e *Error) WithCause(cause error) *Error {
|
|
e.Cause = cause
|
|
return e
|
|
}
|
|
|
|
func (e *Error) ControlError() *rvboxv1.ControlError {
|
|
return &rvboxv1.ControlError{
|
|
Code: e.Code,
|
|
Message: boundUTF8(e.Message, MaxProtocolDetailBytes),
|
|
Retryable: e.Retryable,
|
|
IssueUuid: e.IssueUUID,
|
|
}
|
|
}
|
|
|
|
func DefaultRetryable(code rvboxv1.ControlError_Code) bool {
|
|
switch code {
|
|
case rvboxv1.ControlError_OFFLINE,
|
|
rvboxv1.ControlError_CAPACITY_EXHAUSTED,
|
|
rvboxv1.ControlError_TRANSIENT,
|
|
rvboxv1.ControlError_INTERNAL:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func NewExecutionContextUnavailable(message, issueUUID string) *Error {
|
|
return NewError(rvboxv1.ControlError_CODE_EXECUTION_CONTEXT_UNAVAILABLE, message, issueUUID)
|
|
}
|
|
|
|
func NewElevationUnavailable(message, issueUUID string) *Error {
|
|
return NewError(rvboxv1.ControlError_CODE_ELEVATION_UNAVAILABLE, message, issueUUID)
|
|
}
|
|
|
|
func boundUTF8(value string, limit int) string {
|
|
if len(value) <= limit {
|
|
return value
|
|
}
|
|
value = value[:limit]
|
|
for !utf8.ValidString(value) {
|
|
value = value[:len(value)-1]
|
|
}
|
|
return value
|
|
}
|