diff options
| -rw-r--r-- | internal/gtserror/error.go | 14 | ||||
| -rw-r--r-- | internal/media/util.go | 6 | ||||
| -rw-r--r-- | internal/processing/common/media.go | 24 | 
3 files changed, 37 insertions, 7 deletions
| diff --git a/internal/gtserror/error.go b/internal/gtserror/error.go index a39b5475c..bd83a8dc8 100644 --- a/internal/gtserror/error.go +++ b/internal/gtserror/error.go @@ -40,8 +40,22 @@ const (  	notRelevantKey  	spamKey  	notPermittedKey +	limitReachedKey  ) +// LimitReached indicates that this error was caused by +// some kind of limit being reached, e.g. media upload limit. +func LimitReached(err error) bool { +	_, ok := errors.Value(err, limitReachedKey).(struct{}) +	return ok +} + +// SetLimitReached will wrap the given error to store a "limit reached" +// flag, returning wrapped error. See LimitReached() for example use-cases. +func SetLimitReached(err error) error { +	return errors.WithValue(err, limitReachedKey, struct{}{}) +} +  // IsUnretrievable indicates that a call to retrieve a resource  // (account, status, attachment, etc) could not be fulfilled, either  // because it was not found locally, or because some prerequisite diff --git a/internal/media/util.go b/internal/media/util.go index 22121a546..538d6f572 100644 --- a/internal/media/util.go +++ b/internal/media/util.go @@ -29,6 +29,7 @@ import (  	"codeberg.org/gruf/go-bytesize"  	"codeberg.org/gruf/go-iotools"  	"codeberg.org/gruf/go-mimetypes" +	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  )  // file represents one file @@ -143,8 +144,9 @@ func drainToTmp(rc io.ReadCloser) (string, error) {  	// Check to see if limit was reached,  	// (produces more useful error messages). -	if lr != nil && !iotools.AtEOF(lr.R) { -		return path, fmt.Errorf("reached read limit %s", bytesize.Size(limit)) +	if lr != nil && lr.N <= 0 { +		err := fmt.Errorf("reached read limit %s", bytesize.Size(limit)) +		return path, gtserror.SetLimitReached(err)  	}  	return path, nil diff --git a/internal/processing/common/media.go b/internal/processing/common/media.go index 7baf30345..7957470cd 100644 --- a/internal/processing/common/media.go +++ b/internal/processing/common/media.go @@ -22,6 +22,7 @@ import (  	"errors"  	"fmt" +	"github.com/superseriousbusiness/gotosocial/internal/config"  	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"  	"github.com/superseriousbusiness/gotosocial/internal/media" @@ -51,11 +52,18 @@ func (p *Processor) StoreLocalMedia(  	// Immediately trigger write to storage.  	attachment, err := processing.Load(ctx) -	if err != nil { -		const text = "error processing emoji" +	switch { +	case gtserror.LimitReached(err): +		limit := config.GetMediaLocalMaxSize() +		text := fmt.Sprintf("local media size limit reached: %s", limit) +		return nil, gtserror.NewErrorUnprocessableEntity(err, text) + +	case err != nil: +		const text = "error processing media"  		err := gtserror.Newf("error processing media: %w", err)  		return nil, gtserror.NewErrorUnprocessableEntity(err, text) -	} else if attachment.Type == gtsmodel.FileTypeUnknown { + +	case attachment.Type == gtsmodel.FileTypeUnknown:  		text := fmt.Sprintf("could not process %s type media", attachment.File.ContentType)  		return nil, gtserror.NewErrorUnprocessableEntity(errors.New(text), text)  	} @@ -86,9 +94,15 @@ func (p *Processor) StoreLocalEmoji(  		return nil, gtserror.NewErrorInternalError(err)  	} -	// Immediately write to storage. +	// Immediately trigger write to storage.  	emoji, err := processing.Load(ctx) -	if err != nil { +	switch { +	case gtserror.LimitReached(err): +		limit := config.GetMediaEmojiLocalMaxSize() +		text := fmt.Sprintf("local emoji size limit reached: %s", limit) +		return nil, gtserror.NewErrorUnprocessableEntity(err, text) + +	case err != nil:  		const text = "error processing emoji"  		err := gtserror.Newf("error processing emoji %s: %w", shortcode, err)  		return nil, gtserror.NewErrorUnprocessableEntity(err, text) | 
