afero icon indicating copy to clipboard operation
afero copied to clipboard

More afero branded error returns?

Open wrouesnel opened this issue 10 months ago • 1 comments

I'm currently trying to implement a new afero FS, and one thing which is hitting me is the relatively limited selection of afero filesystem error codes.

Afero currently defines the following:

	ErrFileClosed        = errors.New("File is closed")
	ErrOutOfRange        = errors.New("out of range")
	ErrTooLarge          = errors.New("too large")
	ErrFileNotFound      = os.ErrNotExist
	ErrFileExists        = os.ErrExist
	ErrDestinationExists = os.ErrExist

Within my mental model of it though, it seems like this should be a somewhat wider set of codes so that at the very least when using afero the first thing you receive back is an "afero" branded error, rather then some other type - even if it's just a mapping to a golang built in.

From the list above then it feels like we're missing a couple which would make logical sense here - i.e. ErrPermission and ErrDeadlineExceeded (which is rendered as i/o timeout, which is at least adequate for a good number of possible non-specific failures you might use an afero filesystem for).

There's also some which are syscall specific but probably should have an afero representation i.e. syscall.ENOTDIR has a lot of obvious use, but the syscall library is platform specific whereas afero potentially isn't.

Finally there's a general need for some type of "error in the filesystem" return. Depending what you're doing a lot can happen, and within an implementation the main thing I know is that the user knows they're using Afero since they must've instantiated it at some point: so if my backing logic falls apart from me say, mid-Readdir call, what I want to kick back is some kind of general error that says "hey, this isn't a you problem, it's a me problem but everything is also broken" (i.e. ErrFilesystem or something.)

wrouesnel avatar Apr 20 '25 01:04 wrouesnel

A bit of a related rant, sorry, but how are errors defined here anyway? Packages gcsfs and mem define their own errors, while tarfs and zipfs use errors defined in afero. I get that implementations might require specific errors, but common errors should be the same so users can exchange one fs implementation for another. And right now this is not the case.

ErrFileNotFound is defined in multiple packages as os.ErrNotExist, so it will mostly work, one can check them all as afero.ErrFileNotFound. One exception is GCSFs where it is syscall.ENOENT for some reason!

ErrFileClosed is defined in multiple packages separately as errors.New("File is closed"), even thought there is os.ErrClosed. And surprisingly OsFs seems to actually return os.ErrClosed instead of ErrFileClosed.

Some careful refactoring is needed. Packages should use common afero errors in my opinion. FS-specific errors can be left in their packages.

I agree with you that ErrPermission and ErrDeadlineExcceded are needed as well. ErrFilesystem is better than not having it but probably needs a better name

i512 avatar Apr 24 '25 15:04 i512