github.com/avfs/avfs@v0.33.1-0.20240303173310-c6ba67c33eb7/errors.go (about) 1 // 2 // Copyright 2021 The AVFS authors 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package avfs 18 19 import ( 20 "io/fs" 21 "reflect" 22 "strconv" 23 ) 24 25 // AlreadyExistsGroupError is returned when the group name already exists. 26 type AlreadyExistsGroupError string 27 28 func (e AlreadyExistsGroupError) Error() string { 29 return "group: group " + string(e) + " already exists" 30 } 31 32 // AlreadyExistsUserError is returned when the user name already exists. 33 type AlreadyExistsUserError string 34 35 func (e AlreadyExistsUserError) Error() string { 36 return "user: user " + string(e) + " already exists" 37 } 38 39 // UnknownError is returned when there is an unknown error. 40 type UnknownError string 41 42 func (e UnknownError) Error() string { 43 return "unknown error " + reflect.TypeOf(e).String() + " : '" + string(e) + "'" 44 } 45 46 // UnknownGroupError is returned by LookupGroup when a group cannot be found. 47 type UnknownGroupError string 48 49 func (e UnknownGroupError) Error() string { 50 return "group: unknown group " + string(e) 51 } 52 53 // UnknownGroupIdError is returned by LookupGroupId when a group cannot be found. 54 type UnknownGroupIdError int 55 56 func (e UnknownGroupIdError) Error() string { 57 return "group: unknown groupid " + strconv.Itoa(int(e)) 58 } 59 60 // UnknownUserError is returned by Lookup when a user cannot be found. 61 type UnknownUserError string 62 63 func (e UnknownUserError) Error() string { 64 return "user: unknown user " + string(e) 65 } 66 67 // UnknownUserIdError is returned by LookupUserId when a user cannot be found. 68 type UnknownUserIdError int 69 70 func (e UnknownUserIdError) Error() string { 71 return "user: unknown userid " + strconv.Itoa(int(e)) 72 } 73 74 // ErrorIdentifier is the interface that wraps the Is method of an error. 75 type ErrorIdentifier interface { 76 error 77 78 // Is returns true if the error can be treated as equivalent to a target error. 79 // target is one of fs.ErrPermission, fs.ErrExist, fs.ErrNotExist. 80 Is(target error) bool 81 } 82 83 const customErrorBase = 2 << 30 84 85 type CustomError uintptr 86 87 //go:generate stringer -type CustomError -linecomment -output errors_custom.go 88 89 const ( 90 ErrNegativeOffset CustomError = customErrorBase + 1 // negative offset 91 ErrFileClosing CustomError = customErrorBase + 2 // use of closed file 92 ErrPatternHasSeparator CustomError = customErrorBase + 3 // pattern contains path separator 93 ErrVolumeAlreadyExists CustomError = customErrorBase + 4 // Volume already exists. 94 ErrVolumeNameInvalid CustomError = customErrorBase + 5 // Volume name is invalid. 95 ErrVolumeWindows CustomError = customErrorBase + 6 // Volumes are available for Windows only. 96 ) 97 98 func (i CustomError) Error() string { 99 return i.String() 100 } 101 102 // LinuxError replaces syscall.Errno for Linux operating systems. 103 type LinuxError uintptr 104 105 //go:generate stringer -type LinuxError -linecomment -output errors_forlinux.go 106 107 // Errors for Linux operating systems. 108 // See https://github.com/torvalds/linux/blob/master/tools/include/uapi/asm-generic/errno-base.h 109 const ( 110 ErrBadFileDesc LinuxError = errEBADF // bad file descriptor 111 ErrCrossDevLink LinuxError = errEXDEV // invalid cross-device link 112 ErrDirNotEmpty LinuxError = errENOTEMPTY // directory not empty 113 ErrFileExists LinuxError = errEEXIST // file exists 114 ErrInvalidArgument LinuxError = errEINVAL // invalid argument 115 ErrIsADirectory LinuxError = errEISDIR // is a directory 116 ErrNoSuchFileOrDir LinuxError = errENOENT // no such file or directory 117 ErrNotADirectory LinuxError = errENOTDIR // not a directory 118 ErrOpNotPermitted LinuxError = errEPERM // operation not permitted 119 ErrPermDenied LinuxError = errEACCES // permission denied 120 ErrTooManySymlinks LinuxError = errELOOP // too many levels of symbolic links 121 122 errEACCES = 0xd 123 errEBADF = 0x9 124 errEEXIST = 0x11 125 errEINVAL = 0x16 126 errEISDIR = 0x15 127 errENOENT = 0x2 128 errELOOP = 0x28 129 errENOTDIR = 0x14 130 errENOTEMPTY = 0x27 131 errEPERM = 0x1 132 errEXDEV = 0x12 133 ) 134 135 // Error returns the error string of the Linux operating system. 136 func (i LinuxError) Error() string { 137 return i.String() 138 } 139 140 // Is returns true if the LinuxError can be treated as equivalent to a target error. 141 // target is one of fs.ErrPermission, fs.ErrExist, fs.ErrNotExist. 142 func (i LinuxError) Is(target error) bool { 143 switch target { 144 case fs.ErrPermission: 145 return i == ErrPermDenied || i == ErrOpNotPermitted 146 case fs.ErrExist: 147 return i == ErrFileExists || i == ErrDirNotEmpty 148 case fs.ErrNotExist: 149 return i == ErrNoSuchFileOrDir 150 } 151 152 return false 153 } 154 155 // WindowsError replaces syscall.Errno for Windows operating systems. 156 type WindowsError uintptr 157 158 //go:generate stringer -type WindowsError -linecomment -output errors_forwindows.go 159 160 // Errors for Windows operating systems. 161 // See https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes 162 const ( 163 ErrWinAccessDenied WindowsError = 5 // Access is denied. 164 ErrWinAlreadyExists WindowsError = 183 // Cannot create a file when that file already exists. 165 ErrWinBadNetPath WindowsError = 53 // Bad network path. 166 ErrWinDirNameInvalid WindowsError = 0x10B // The directory name is invalid. 167 ErrWinDirNotEmpty WindowsError = 145 // The directory is not empty. 168 ErrWinFileExists WindowsError = 80 // The file exists. 169 ErrWinFileNotFound WindowsError = 2 // The system cannot find the file specified. 170 ErrWinIncorrectFunc WindowsError = 1 // Incorrect function. 171 ErrWinIsADirectory WindowsError = 21 // is a directory 172 ErrWinNegativeSeek WindowsError = 0x83 // An attempt was made to move the file pointer before the beginning of the file. 173 ErrWinNotReparsePoint WindowsError = 4390 // The file or directory is not a reparse point. 174 ErrWinInvalidHandle WindowsError = 6 // The handle is invalid. 175 ErrWinSharingViolation WindowsError = 32 // The process cannot access the file because it is being used by another process. 176 ErrWinNotSupported WindowsError = 0x20000082 // not supported by windows 177 ErrWinPathNotFound WindowsError = 3 // The system cannot find the path specified. 178 ErrWinPrivilegeNotHeld WindowsError = 1314 // A required privilege is not held by the client. 179 ) 180 181 // Error returns the error string of the Windows operating system. 182 func (i WindowsError) Error() string { 183 return i.String() 184 } 185 186 // Is returns true if the WindowsError can be treated as equivalent to a target error. 187 // target is one of fs.ErrPermission, fs.ErrExist, fs.ErrNotExist. 188 func (i WindowsError) Is(target error) bool { 189 switch target { 190 case fs.ErrPermission: 191 return i == ErrWinAccessDenied 192 case fs.ErrExist: 193 return i == ErrWinAlreadyExists || i == ErrWinDirNotEmpty || i == ErrWinFileExists 194 case fs.ErrNotExist: 195 return i == ErrWinFileNotFound || i == ErrWinBadNetPath || i == ErrWinPathNotFound 196 } 197 198 return false 199 } 200 201 // Errors regroups errors depending on the OS emulated. 202 type Errors struct { 203 BadFileDesc error // bad file descriptor. 204 DirNotEmpty error // Directory not empty. 205 FileExists error // File exists. 206 InvalidArgument error // invalid argument 207 IsADirectory error // File Is a directory. 208 NoSuchDir error // No such directory. 209 NoSuchFile error // No such file. 210 NotADirectory error // Not a directory. 211 OpNotPermitted error // operation not permitted. 212 PermDenied error // Permission denied. 213 TooManySymlinks error // Too many levels of symbolic links. 214 } 215 216 // SetOSType sets errors depending on the operating system. 217 func (e *Errors) SetOSType(osType OSType) { 218 switch osType { 219 case OsWindows: 220 e.BadFileDesc = ErrWinAccessDenied 221 e.DirNotEmpty = ErrWinDirNotEmpty 222 e.FileExists = ErrWinFileExists 223 e.InvalidArgument = ErrWinNegativeSeek 224 e.IsADirectory = ErrWinIsADirectory 225 e.NoSuchDir = ErrWinPathNotFound 226 e.NoSuchFile = ErrWinFileNotFound 227 e.NotADirectory = ErrWinPathNotFound 228 e.OpNotPermitted = ErrWinNotSupported 229 e.PermDenied = ErrWinAccessDenied 230 e.TooManySymlinks = ErrTooManySymlinks 231 default: 232 e.BadFileDesc = ErrBadFileDesc 233 e.DirNotEmpty = ErrDirNotEmpty 234 e.FileExists = ErrFileExists 235 e.InvalidArgument = ErrInvalidArgument 236 e.IsADirectory = ErrIsADirectory 237 e.NoSuchDir = ErrNoSuchFileOrDir 238 e.NoSuchFile = ErrNoSuchFileOrDir 239 e.NotADirectory = ErrNotADirectory 240 e.OpNotPermitted = ErrOpNotPermitted 241 e.PermDenied = ErrPermDenied 242 e.TooManySymlinks = ErrTooManySymlinks 243 } 244 }