Explorar o código

Return detector errors from imagetype.Detect

DarthSim hai 1 mes
pai
achega
bd5751737c
Modificáronse 3 ficheiros con 64 adicións e 1 borrados
  1. 17 0
      imagetype/errors.go
  2. 5 1
      imagetype/registry.go
  3. 42 0
      imagetype/registry_test.go

+ 17 - 0
imagetype/errors.go

@@ -7,9 +7,26 @@ import (
 )
 
 type (
+	TypeDetectionError struct{ error }
 	UnknownFormatError struct{}
 )
 
+func newTypeDetectionError(err error) error {
+	return ierrors.Wrap(
+		TypeDetectionError{err},
+		1,
+		ierrors.WithStatusCode(http.StatusUnprocessableEntity),
+		ierrors.WithPublicMessage("Failed to detect source image type"),
+		ierrors.WithShouldReport(false),
+	)
+}
+
+func (e TypeDetectionError) Error() string {
+	return "Failed to detect image type: " + e.error.Error()
+}
+
+func (e TypeDetectionError) Unwrap() error { return e.error }
+
 func newUnknownFormatError() error {
 	return ierrors.Wrap(
 		UnknownFormatError{},

+ 5 - 1
imagetype/registry.go

@@ -151,7 +151,11 @@ func (r *registry) Detect(re io.Reader) (Type, error) {
 
 	for _, fn := range r.detectors {
 		br.Rewind()
-		if typ, err := fn(br); err == nil && typ != Unknown {
+		typ, err := fn(br)
+		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
+			return Unknown, newTypeDetectionError(err)
+		}
+		if err == nil && typ != Unknown {
 			return typ, nil
 		}
 	}

+ 42 - 0
imagetype/registry_test.go

@@ -1,6 +1,8 @@
 package imagetype
 
 import (
+	"io"
+	"strings"
 	"testing"
 
 	"github.com/imgproxy/imgproxy/v3/bufreader"
@@ -176,3 +178,43 @@ func TestRegisterMagicBytes(t *testing.T) {
 	// Verify the magic bytes are registered
 	require.Len(t, testRegistry.detectors, 1)
 }
+
+func TestDetectionErrorReturns(t *testing.T) {
+	// Create a test registry to avoid interfering with global state
+	testRegistry := NewRegistry()
+
+	detErr := error(nil)
+
+	// The first detector will fail with detErr
+	testRegistry.RegisterDetector(func(r bufreader.ReadPeeker) (Type, error) {
+		return Unknown, detErr
+	})
+
+	// The second detector will succeed
+	testRegistry.RegisterDetector(func(r bufreader.ReadPeeker) (Type, error) {
+		return JPEG, nil
+	})
+
+	// We don't actually need to read anything, just create a reader
+	r := strings.NewReader("")
+
+	// Should not fail with io.EOF
+	detErr = io.EOF
+	typ, err := testRegistry.Detect(r)
+	require.Equal(t, JPEG, typ)
+	require.NoError(t, err)
+
+	// Should not fail with io.ErrUnexpectedEOF
+	detErr = io.ErrUnexpectedEOF
+	typ, err = testRegistry.Detect(r)
+	require.Equal(t, JPEG, typ)
+	require.NoError(t, err)
+
+	// Should fail with other read errors
+	detErr = io.ErrClosedPipe
+	typ, err = testRegistry.Detect(r)
+	require.Equal(t, Unknown, typ)
+	require.Error(t, err)
+	require.ErrorAs(t, err, &TypeDetectionError{})
+	require.ErrorIs(t, err, io.ErrClosedPipe)
+}