mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-08-11 05:56:55 +00:00
feat(apierr): add UpstreamError type for typed upstream failures
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
// Package apierr translates upstream (Garage Admin API, S3/MinIO) errors into
|
||||
// backend API error responses with correct HTTP status codes and stable codes.
|
||||
package apierr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// UpstreamError is a typed error describing a failure reported by an upstream
|
||||
// service. Returned from the services layer and consumed by handlers via Map
|
||||
// or Respond.
|
||||
type UpstreamError struct {
|
||||
HTTPStatus int
|
||||
Code string // upstream code, e.g. "BucketNotEmpty", "NoSuchKey"
|
||||
Message string // human-readable upstream message
|
||||
Source string // "garage" or "s3"
|
||||
Details map[string]string // optional: region, path, bucket, key
|
||||
}
|
||||
|
||||
func (e *UpstreamError) Error() string {
|
||||
if e.Code == "" {
|
||||
return fmt.Sprintf("%s: %s", e.Source, e.Message)
|
||||
}
|
||||
return fmt.Sprintf("%s %s: %s", e.Source, e.Code, e.Message)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package apierr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUpstreamError_Error(t *testing.T) {
|
||||
e := &UpstreamError{
|
||||
HTTPStatus: 409,
|
||||
Code: "BucketNotEmpty",
|
||||
Message: "Tried to delete a non-empty bucket",
|
||||
Source: "garage",
|
||||
}
|
||||
got := e.Error()
|
||||
want := "garage BucketNotEmpty: Tried to delete a non-empty bucket"
|
||||
if got != want {
|
||||
t.Fatalf("Error() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpstreamError_ErrorWithoutCode(t *testing.T) {
|
||||
e := &UpstreamError{HTTPStatus: 500, Source: "garage", Message: "server went boom"}
|
||||
got := e.Error()
|
||||
want := "garage: server went boom"
|
||||
if got != want {
|
||||
t.Fatalf("Error() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpstreamError_ErrorsAs(t *testing.T) {
|
||||
var base error = &UpstreamError{HTTPStatus: 404, Code: "NoSuchBucket", Source: "garage"}
|
||||
var target *UpstreamError
|
||||
if !errors.As(base, &target) {
|
||||
t.Fatal("errors.As should have matched *UpstreamError")
|
||||
}
|
||||
if target.Code != "NoSuchBucket" {
|
||||
t.Fatalf("Code = %q, want NoSuchBucket", target.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user