mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-08-10 13:36:53 +00:00
feat(apierr): convert MinIO errors to UpstreamError via FromMinio
This commit is contained in:
@@ -2,9 +2,11 @@ package apierr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/Noooste/azuretls-client"
|
||||
"github.com/minio/minio-go/v7"
|
||||
)
|
||||
|
||||
// garageErrBody mirrors Garage's JSON error envelope.
|
||||
@@ -51,3 +53,40 @@ func ParseGarage(resp *azuretls.Response) error {
|
||||
}
|
||||
return ue
|
||||
}
|
||||
|
||||
// FromMinio converts a MinIO/S3 error into an *UpstreamError. Returns nil when
|
||||
// err is nil. If err is not a minio.ErrorResponse (e.g. a network error), a
|
||||
// generic 500 *UpstreamError is returned with the raw error string as Message.
|
||||
func FromMinio(err error) *UpstreamError {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mer minio.ErrorResponse
|
||||
if errors.As(err, &mer) {
|
||||
details := map[string]string{}
|
||||
if mer.BucketName != "" {
|
||||
details["bucket"] = mer.BucketName
|
||||
}
|
||||
if mer.Key != "" {
|
||||
details["key"] = mer.Key
|
||||
}
|
||||
status := mer.StatusCode
|
||||
if status == 0 {
|
||||
status = 500
|
||||
}
|
||||
return &UpstreamError{
|
||||
HTTPStatus: status,
|
||||
Code: mer.Code,
|
||||
Message: mer.Message,
|
||||
Source: "s3",
|
||||
Details: details,
|
||||
}
|
||||
}
|
||||
|
||||
return &UpstreamError{
|
||||
HTTPStatus: 500,
|
||||
Source: "s3",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package apierr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Noooste/azuretls-client"
|
||||
"github.com/minio/minio-go/v7"
|
||||
)
|
||||
|
||||
func fakeResp(status int, body string) *azuretls.Response {
|
||||
@@ -77,3 +79,56 @@ func TestParseGarage_EmptyBody(t *testing.T) {
|
||||
t.Errorf("HTTPStatus = %d, want 502", ue.HTTPStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromMinio_NilInput(t *testing.T) {
|
||||
if got := FromMinio(nil); got != nil {
|
||||
t.Fatalf("FromMinio(nil) = %v, want nil", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromMinio_MinioErrorResponse(t *testing.T) {
|
||||
in := minio.ErrorResponse{
|
||||
StatusCode: 404,
|
||||
Code: "NoSuchBucket",
|
||||
Message: "The specified bucket does not exist",
|
||||
BucketName: "missing",
|
||||
}
|
||||
got := FromMinio(in)
|
||||
if got == nil {
|
||||
t.Fatal("FromMinio returned nil")
|
||||
}
|
||||
if got.HTTPStatus != 404 {
|
||||
t.Errorf("HTTPStatus = %d, want 404", got.HTTPStatus)
|
||||
}
|
||||
if got.Code != "NoSuchBucket" {
|
||||
t.Errorf("Code = %q, want NoSuchBucket", got.Code)
|
||||
}
|
||||
if got.Message != "The specified bucket does not exist" {
|
||||
t.Errorf("Message = %q", got.Message)
|
||||
}
|
||||
if got.Source != "s3" {
|
||||
t.Errorf("Source = %q, want s3", got.Source)
|
||||
}
|
||||
if got.Details["bucket"] != "missing" {
|
||||
t.Errorf("Details[bucket] = %q, want missing", got.Details["bucket"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromMinio_NonMinioError(t *testing.T) {
|
||||
got := FromMinio(errors.New("connection refused"))
|
||||
if got == nil {
|
||||
t.Fatal("FromMinio returned nil")
|
||||
}
|
||||
if got.HTTPStatus != 500 {
|
||||
t.Errorf("HTTPStatus = %d, want 500", got.HTTPStatus)
|
||||
}
|
||||
if got.Code != "" {
|
||||
t.Errorf("Code = %q, want empty", got.Code)
|
||||
}
|
||||
if !strings.Contains(got.Message, "connection refused") {
|
||||
t.Errorf("Message = %q", got.Message)
|
||||
}
|
||||
if got.Source != "s3" {
|
||||
t.Errorf("Source = %q, want s3", got.Source)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user