386 lines
9.6 KiB
Go
386 lines
9.6 KiB
Go
package errno
|
|
|
|
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:
|
|
//
|
|
// EINVAL When the id provided is not >32767
|
|
// EIDINUSE When the ID is already in use.
|
|
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
|
|
}
|