mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 06:32:26 -05:00 
			
		
		
		
	[bugfix] fix media limit reader check (#3363)
* return nicer errors for frontend when media / emoji upload limit reached * fix reader limit check * add code comment
This commit is contained in:
		
					parent
					
						
							
								c1c8849322
							
						
					
				
			
			
				commit
				
					
						497ebd8c4e
					
				
			
		
					 3 changed files with 37 additions and 7 deletions
				
			
		|  | @ -40,8 +40,22 @@ const ( | ||||||
| 	notRelevantKey | 	notRelevantKey | ||||||
| 	spamKey | 	spamKey | ||||||
| 	notPermittedKey | 	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 | // IsUnretrievable indicates that a call to retrieve a resource | ||||||
| // (account, status, attachment, etc) could not be fulfilled, either | // (account, status, attachment, etc) could not be fulfilled, either | ||||||
| // because it was not found locally, or because some prerequisite | // because it was not found locally, or because some prerequisite | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ import ( | ||||||
| 	"codeberg.org/gruf/go-bytesize" | 	"codeberg.org/gruf/go-bytesize" | ||||||
| 	"codeberg.org/gruf/go-iotools" | 	"codeberg.org/gruf/go-iotools" | ||||||
| 	"codeberg.org/gruf/go-mimetypes" | 	"codeberg.org/gruf/go-mimetypes" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // file represents one file | // file represents one file | ||||||
|  | @ -143,8 +144,9 @@ func drainToTmp(rc io.ReadCloser) (string, error) { | ||||||
| 
 | 
 | ||||||
| 	// Check to see if limit was reached, | 	// Check to see if limit was reached, | ||||||
| 	// (produces more useful error messages). | 	// (produces more useful error messages). | ||||||
| 	if lr != nil && !iotools.AtEOF(lr.R) { | 	if lr != nil && lr.N <= 0 { | ||||||
| 		return path, fmt.Errorf("reached read limit %s", bytesize.Size(limit)) | 		err := fmt.Errorf("reached read limit %s", bytesize.Size(limit)) | ||||||
|  | 		return path, gtserror.SetLimitReached(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return path, nil | 	return path, nil | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/media" | 	"github.com/superseriousbusiness/gotosocial/internal/media" | ||||||
|  | @ -51,11 +52,18 @@ func (p *Processor) StoreLocalMedia( | ||||||
| 
 | 
 | ||||||
| 	// Immediately trigger write to storage. | 	// Immediately trigger write to storage. | ||||||
| 	attachment, err := processing.Load(ctx) | 	attachment, err := processing.Load(ctx) | ||||||
| 	if err != nil { | 	switch { | ||||||
| 		const text = "error processing emoji" | 	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) | 		err := gtserror.Newf("error processing media: %w", err) | ||||||
| 		return nil, gtserror.NewErrorUnprocessableEntity(err, text) | 		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) | 		text := fmt.Sprintf("could not process %s type media", attachment.File.ContentType) | ||||||
| 		return nil, gtserror.NewErrorUnprocessableEntity(errors.New(text), text) | 		return nil, gtserror.NewErrorUnprocessableEntity(errors.New(text), text) | ||||||
| 	} | 	} | ||||||
|  | @ -86,9 +94,15 @@ func (p *Processor) StoreLocalEmoji( | ||||||
| 		return nil, gtserror.NewErrorInternalError(err) | 		return nil, gtserror.NewErrorInternalError(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Immediately write to storage. | 	// Immediately trigger write to storage. | ||||||
| 	emoji, err := processing.Load(ctx) | 	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" | 		const text = "error processing emoji" | ||||||
| 		err := gtserror.Newf("error processing emoji %s: %w", shortcode, err) | 		err := gtserror.Newf("error processing emoji %s: %w", shortcode, err) | ||||||
| 		return nil, gtserror.NewErrorUnprocessableEntity(err, text) | 		return nil, gtserror.NewErrorUnprocessableEntity(err, text) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue