cworthy/errno/err.go

386 lines
9.6 KiB
Go
Raw Normal View History

2022-11-01 07:09:52 -04:00
package errno
2021-08-29 12:27:05 -04:00
type ErrorT uint16
const (
NULL ErrorT = iota
/****************
* Posix Errors *
****************/
// Argument list too long.
E2BIG
// Permission denied.
EACCES
// Address in use.
EADDRINUSE
// Address not available.
EADDRNOTAVAIL
// Address family not supported.
EAFNOSUPPORT
// Resource unavailable, try again.
EAGAIN
// Connection already in progress.
EALREADY
// Bad file descriptor.
EBADF
// Bad message.
EBADMSG
// Device or resource busy.
EBUSY
// Operation canceled.
ECANCELED
// No child processes.
ECHILD
// Connection aborted.
ECONNABORTED
// Connection refused.
ECONNREFUSED
// Connection reset.
ECONNRESET
// Resource deadlock would occur.
EDEADLK
// Destination address required.
EDESTADDRREQ
// Mathematics argument out of domain of function.
EDOM
// Reserved.
EDQUOT
// File exists.
EEXIST
// Bad address.
EFAULT
// File too large.
EFBIG
// Host is unreachable.
EHOSTUNREACH
// Identifier removed.
EIDRM
// Illegal byte sequence.
EILSEQ
// Operation in progress.
EINPROGRESS
// Interrupted function.
EINTR
// Invalid argument.
EINVAL
// I/O error.
EIO
// Socket is connected.
EISCONN
// Is a directory.
EISDIR
// Too many levels of symbolic links.
ELOOP
// File descriptor value too large.
EMFILE
// Too many links.
EMLINK
// Message too large.
EMSGSIZE
// Reserved.
EMULTIHOP
// Filename too long.
ENAMETOOLONG
// Network is down.
ENETDOWN
// Connection aborted by network.
ENETRESET
// Network unreachable.
ENETUNREACH
// Too many files open in system.
ENFILE
// No buffer space available.
ENOBUFS
// No message is available on the STREAM head read queue.
ENODATA
// No such device.
ENODEV
// No such file or directory.
ENOENT
// Executable file format error.
ENOEXEC
// No locks available.
ENOLCK
// Reserved.
ENOLINK
// Not enough space.
ENOMEM
// No message of the desired type.
ENOMSG
// Protocol not available.
ENOPROTOOPT
// No space left on device.
ENOSPC
// No STREAM resources.
ENOSR
// Not a STREAM.
ENOSTR
// Functionality not supported.
ENOSYS
// The socket is not connected.
ENOTCONN
// Not a directory or a symbolic link to a directory.
ENOTDIR
// Directory not empty.
ENOTEMPTY
// State not recoverable.
ENOTRECOVERABLE
// Not a socket.
ENOTSOCK
// Not supported.
ENOTSUP
// Inappropriate I/O control operation.
ENOTTY
// No such device or address.
ENXIO
// Operation not supported on socket.
EOPNOTSUPP
// Value too large to be stored in data type.
EOVERFLOW
// Previous owner died.
EOWNERDEAD
// Operation not permitted.
EPERM
// Broken pipe.
EPIPE
// Protocol error.
EPROTO
// Protocol not supported.
EPROTONOSUPPORT
// Protocol wrong type for socket.
EPROTOTYPE
// Result too large.
ERANGE
// Read-only file system.
EROFS
// Invalid seek.
ESPIPE
// No such process.
ESRCH
// Reserved.
ESTALE
// Stream ioctl() timeout.
ETIME
// Connection timed out.
ETIMEDOUT
// Text file busy.
ETXTBSY
// Operation would block.
EWOULDBLOCK
// Cross-device link.
EXDEV
/*************************
* ErrGo Specific Errors *
*************************/
// Generic error.
EOTHER ErrorT = 16384 + iota
// ID is already in use.
EIDINUSE
// Already set.
EALREADYSET
// Not found.
ENOTFOUND
)
var errorTable = map[ErrorT]string{
/****************
* Posix Errors *
****************/
E2BIG: "Argument list too long",
EACCES: "Permission denied",
EADDRINUSE: "Address in use",
EADDRNOTAVAIL: "Address not available",
EAFNOSUPPORT: "Address family not supported",
EAGAIN: "Resource unavailable, try again",
EALREADY: "Connection already in progress",
EBADF: "Bad file descriptor",
EBADMSG: "Bad message",
EBUSY: "Device or resource busy",
ECANCELED: "Operation canceled",
ECHILD: "No child processes",
ECONNABORTED: "Connection aborted",
ECONNREFUSED: "Connection refused",
ECONNRESET: "Connection reset",
EDEADLK: "Resource deadlock would occur",
EDESTADDRREQ: "Destination address required",
EDOM: "Mathematics argument out of domain of function",
EDQUOT: "Reserved",
EEXIST: "File exists",
EFAULT: "Bad address",
EFBIG: "File too large",
EHOSTUNREACH: "Host is unreachable",
EIDRM: "Identifier removed",
EILSEQ: "Illegal byte sequence",
EINPROGRESS: "Operation in progress",
EINTR: "Interrupted function",
EINVAL: "Invalid argument",
EIO: "I/O error",
EISCONN: "Socket is connected",
EISDIR: "Is a directory",
ELOOP: "Too many levels of symbolic links",
EMFILE: "File descriptor value too large",
EMLINK: "Too many links",
EMSGSIZE: "Message too large",
EMULTIHOP: "Reserved",
ENAMETOOLONG: "Filename too long",
ENETDOWN: "Network is down",
ENETRESET: "Connection aborted by network",
ENETUNREACH: "Network unreachable",
ENFILE: "Too many files open in system",
ENOBUFS: "No buffer space available",
ENODATA: "No message is available on the STREAM head read queue",
ENODEV: "No such device",
ENOENT: "No such file or directory",
ENOEXEC: "Executable file format error",
ENOLCK: "No locks available",
ENOLINK: "Reserved",
ENOMEM: "Not enough space",
ENOMSG: "No message of the desired type",
ENOPROTOOPT: "Protocol not available",
ENOSPC: "No space left on device",
ENOSR: "No STREAM resources",
ENOSTR: "Not a STREAM",
ENOSYS: "Functionality not supported",
ENOTCONN: "The socket is not connected",
ENOTDIR: "Not a directory or a symbolic link to a directory",
ENOTEMPTY: "Directory not empty",
ENOTRECOVERABLE: "State not recoverable",
ENOTSOCK: "Not a socket",
ENOTSUP: "Not supported",
ENOTTY: "Inappropriate I/O control operation",
ENXIO: "No such device or address",
EOPNOTSUPP: "Operation not supported on socket",
EOVERFLOW: "Value too large to be stored in data type",
EOWNERDEAD: "Previous owner died",
EPERM: "Operation not permitted",
EPIPE: "Broken pipe",
EPROTO: "Protocol error",
EPROTONOSUPPORT: "Protocol not supported",
EPROTOTYPE: "Protocol wrong type for socket",
ERANGE: "Result too large",
EROFS: "Read-only file system",
ESPIPE: "Invalid seek",
ESRCH: "No such process",
ESTALE: "Reserved",
ETIME: "Stream ioctl() timeout",
ETIMEDOUT: "Connection timed out",
ETXTBSY: "Text file busy",
EWOULDBLOCK: "Operation would block",
EXDEV: "Cross-device link",
/*************************
* ErrGo Specific Errors *
*************************/
EOTHER: "Generic error",
EIDINUSE: "ID is already in use",
EALREADYSET: "Already set",
ENOTFOUND: "Not found",
}
const userErrorIDSpaceStart = uint16(1) << 15
var highestUserErrorID uint16 = userErrorIDSpaceStart
// Error is required to satisfy the Go error interface.
func (err ErrorT) Error() string {
return errorTable[err]
}
// RegisterMsg allows you to set the error message on manually created ErrorT's.
func (err ErrorT) RegisterMsg(msg string) error {
if _, nok := errorTable[err]; nok {
return EALREADYSET
}
return nil
}
// MustRegisterMsg is identical to RegisterMsg but will panic on errors.
func (err ErrorT) MustRegisterMsg(msg string) {
if e := err.RegisterMsg(msg); e != nil {
panic(e)
}
}
// ID is shorthand for uint16(err), when err is an ErrorT.
func (err ErrorT) ID() uint16 {
return uint16(err)
}
// NewErrorT is a factory for ErrorT.
// In the event that an invalid id is provided it will return an empty ErrorT in the first value
// and one of the following in the second:
2022-11-01 07:09:52 -04:00
//
// EINVAL When the id provided is not >32767
// EIDINUSE When the ID is already in use.
2021-08-29 12:27:05 -04:00
func NewErrorT(id uint16, msg string) (ErrorT, error) {
if id < userErrorIDSpaceStart {
return ErrorT(0), EINVAL
}
err := ErrorT(id)
if _, nok := errorTable[err]; nok {
return ErrorT(0), EIDINUSE
}
err.MustRegisterMsg(msg)
return err, nil
}
// MustNewErrorT is identical to NewErrorT but will panic on errors.
func MustNewErrorT(id uint16, msg string) ErrorT {
err, e := NewErrorT(id, msg)
if e != nil {
panic(e)
}
return err
}
// NewNextErrorT is a factory for ErrorT which attempt to auto assign an ID >32767 and <65536.
// In the event that 32768 errors have already been created in this way, it will return an empty
// ErrorT in the first value and EOVERFLOW in the second.
func NewNextErrorT(msg string) (ErrorT, error) {
if highestUserErrorID == ^uint16(0) {
return ErrorT(0), EOVERFLOW
}
id := highestUserErrorID
highestUserErrorID++
err := ErrorT(id)
err.MustRegisterMsg(msg)
return err, nil
}
// MustNewNextErrorT is identical to NewNextErrorT but will panic on errors.
func MustNewNextErrorT(msg string) ErrorT {
err, e := NewNextErrorT(msg)
if e != nil {
panic(e)
}
return err
}
// Lookup takes an id and attempts to find an ErrorT which matches it.
func Lookup(id uint16) (err ErrorT, msg string, e error) {
for err, msg := range errorTable {
if uint16(err) == id {
return err, msg, nil
}
}
return ErrorT(0), "", ENOTFOUND
}
// Assert will perform a type assertion on a given error to ErrorT.
func Assert(e error) (ErrorT, error) {
err, ok := e.(ErrorT)
if !ok {
return ErrorT(0), EINVAL
}
return err, nil
}
// MustAssert is identical to Assert but will panic on errors.
func MustAssert(e error) ErrorT {
err, e := Assert(e)
if e != nil {
panic(e)
}
return err
}