If you don't like errors in your code, you will have to fix them. This handy list of Ruby's errors will hopefully help you do so! (And welcome back for the second season of Idiosyncratic Ruby!)
Built-in Exceptions
Exception | Thrown by core Ruby when | Remarks |
---|---|---|
NoMemoryError | The Ruby interpreter could not allocate the required memory | "Idiosyncratic" * 100_000_000_000 |
ScriptError | - | Not thrown directly |
ScriptError → LoadError | A source file could not be loaded, required, or required relatively | It is meant for source code the current program is running and therefore should not be used for other kinds of files |
ScriptError → NotImplementedError | A feature of Ruby does not work on this platform/OS, for example, fork | Although it is often used as "I have not implemented it (yet)", its original purpose is low-level platform support errors |
ScriptError → SyntaxError | Invalid Ruby syntax was found | Do not raise when parsing some other file format fails. It is meant for source code that the current program is running. |
SecurityError | Mostly raised when attempting a forbidden $SAFE level 1 operation | Use as base class for critical security issues, which should intentionally not be rescued by default |
SignalException | A signal is received | The common way to catch a signal is the trap method |
SignalException → Interrupt | An interrupt signal (SIGINT) is received | The common way to catch a signal is the trap method |
StandardError | - | Base class for normal exceptions. See next table. |
SystemExit | Thrown by Kernel#exit | Not thrown by Kernel#exit! |
SystemStackError | Raised for stack overflows, for example, in case of infinite recursion | Cannot always be caught by the interpreter |
fatal | When a deadlock is discovered or this special vm exception is triggered | Never rescuable. You can use this hack to get a reference to the error object: ObjectSpace.each_object(Class){|c| break c if c.ancestors.include?(Exception) && c.name == 'fatal' } |
StandardError
These will be caught by the rescue
statement without defining an explicit error class.
Exception | Thrown by core Ruby when | Remarks |
---|---|---|
ArgumentError | Raised when a method is not given the proper arguments, for example, a wrong argument count | Best class to inherit from for custom errors describing that the method usage was wrong |
ArgumentError → UncaughtThrowError | When throw is used without the proper catch around | - |
EncodingError | Sometimes raised directly in unicode edge cases or when symbols are broken | - |
EncodingError → Encoding:: CompatibilityError | Raised when trying to combine strings of two incompatible encodings | Example: "Idiosyn" +"crätic".encode("UTF-16LE") under UTF-8 leads to Encoding::CompatibilityError: incompatible character encodings: UTF-8 and UTF-16LE |
EncodingError → Encoding:: ConverterNotFoundError | Raised when no encoding converter is available | Example: "Idiosyncrätic".encode("ABC") under UTF-8 leads to Encoding::ConverterNotFoundError: code converter not found (UTF-8 to ABC) |
EncodingError → Encoding:: InvalidByteSequenceError | String contains byte sequences not valid in the current encoding | Example: "Idiosyncr\u{D800}tic".encode("ASCII") under UTF-8 leads to Encoding::InvalidByteSequenceError: "\xED" followed by "\xA0" on UTF-8 |
EncodingError → Encoding:: UndefinedConversionError | Raised when an encoding converter is available, but it cannot convert a specific codepoint | Example: "\u{00A0}".encode("EUC-JP") under UTF-8 leads to Encoding::UndefinedConversionError: U+00A0 from UTF-8 to EUC-JP |
FiberError | Raised when an invalid operation is attempted on a Fiber | Such as: Attempting to call/resume a dead Fiber, yield from the root fiber, calling a Fiber across threads |
IOError | Raised when an IO operation fails, like opening a file | Pay attention that there are some failures will raise a SystemCallError , which is not a sub-class of IOError ! |
IOError → EOFError | Raised by many IO operations when reaching the end of file | - |
IndexError | Raised when an element or deducted value cannot be retrieved, for example, when using Array#fetch | Thrown by many core classes like Array, Regex, String, Struct or some standard libraries like strscan |
IndexError → KeyError | Raised when an element cannot be retrieved (by a key), for example, when using Hash#fetch | Mainly used by hashes |
IndexError → StopIteration | Raised when an external iterator has reached its end | You can use the Kernel#loop method to automatically catch StopIteration |
IndexError → StopIteration → ClosedQueueError | Raised when trying to modify a closed Queue | - |
LocalJumpError | Thrown when an invalid control flow operation is attempted, like calling yield from a method that was not passed a block to |
LocalJumpError s contains a reason and an exit_value property from the last valid context |
Math::DomainError | An invalid mathematical operation was attempted, for example, trying to calculate the arctan of a value greater than 1 | - |
NameError | Raised when referencing things that do not exist, like unknown constants | - |
NameError → NoMethodError | Raised if trying to call a method that does not exist, and no method_missing is defined |
Trying to call non-existent private methods of self (like Kernel#puts ) will result in NameError instead of NoMethodError , because it could also have been a local variable |
RangeError | A numerical number is off, most often it is too small or big | For example, [].pack("C100000000000000000000") does not work, because pack requires the number to fit into long |
RangeError → FloatDomainError | Raised when trying to convert a special Float value (NaN , Float::INFINITY ) to another number format that does not support special values |
- |
RegexpError | Raised when trying to dynamically create an invalid regex | - |
RuntimeError | Unspecific occurrences | Default error class that will be used when raising a string: raise "something" |
RuntimeError → FrozenError | Raised when trying to modify a frozen object | Introduced with Ruby 2.5 |
SystemCallError | - | Lower level system call errors. See next table. |
ThreadError | Raised for invalid Thread operations | - |
TypeError | Violations against Ruby's type system | For example, "" + nil will lead to "TypeError: no implicit conversion of nil into String" |
ZeroDivisionError | An integer, complex, or rational number was tried to divide by another integer, complex, or rational number | Floats and BigDecimal return Infinity, negative Infinity, or NaN |
SystemCallError
These errors are thrown by the operating system under certain circumstances. The exact list depends on your platform and can be found in a file called errno.h
. You get such errors when working with processes, sockets, files, and other functionality that relies on low level system operations.
What follows is the list of errors that are known by Ruby. The error numbers and messages were generated on a recent ubuntu Linux machine. All system call errors are namespaced under Errno::
and can be dynamically created using SystemCallError.new(number)
.
Exception | No | Message | Example One-Liner¹ |
---|---|---|---|
Errno::E2BIG | 7 | Argument list too long | - |
Errno::EACCES | 13 | Permission denied | As non-root: File.read('/root') |
Errno::EADDRINUSE | 98 | Address already in use | require "socket"; 2.times{ TCPServer.new("", 3003) } |
Errno::EADDRNOTAVAIL | 99 | Cannot assign requested address | - |
Errno::EADV | 68 | Advertise error | - |
Errno::EAFNOSUPPORT | 97 | Address family not supported by protocol | - |
Errno::EAGAIN | 11 | Resource temporarily unavailable | - |
Errno::EAGAIN → IO::EAGAINWaitReadable² | - | - | STDIN.read_nonblock(1) (if blocking) |
Errno::EAGAIN → IO::EAGAINWaitWritable² | - | - | - |
Errno::EALREADY | 114 | Operation already in progress | - |
Errno::EBADE | 52 | Invalid exchange | - |
Errno::EBADF | 9 | Bad file descriptor | IO.new(-1) |
Errno::EBADFD | 77 | File descriptor in bad state | - |
Errno::EBADMSG | 74 | Bad message | - |
Errno::EBADR | 53 | Invalid request descriptor | - |
Errno::EBADRQC | 56 | Invalid request code | - |
Errno::EBADSLT | 57 | Invalid slot | - |
Errno::EBFONT | 59 | Bad font file format | - |
Errno::EBUSY | 16 | Device or resource busy | - |
Errno::ECANCELED | 125 | Operation canceled | - |
Errno::ECHILD | 10 | No child processes | Process.wait (with no child processes) |
Errno::ECHRNG | 44 | Channel number out of range | - |
Errno::ECOMM | 70 | Communication error on send | - |
Errno::ECONNABORTED | 103 | Software caused connection abort | - |
Errno::ECONNREFUSED | 111 | Connection refused | require "socket"; TCPSocket.new("", rand(987654321)) |
Errno::ECONNRESET | 104 | Connection reset by peer | - |
Errno::EDEADLK | 35 | Resource deadlock avoided | - |
Errno::EDEADLOCK | 35 | Resource deadlock avoided | - |
Errno::EDESTADDRREQ | 89 | Destination address required | - |
Errno::EDOM | 33 | Numerical argument out of domain | - |
Errno::EDOTDOT | 73 | RFS specific error | - |
Errno::EDQUOT | 122 | Disk quota exceeded | - |
Errno::EEXIST | 17 | File exists | Dir.mkdir("/") |
Errno::EFAULT | 14 | Bad address | - |
Errno::EFBIG | 27 | File too large | - |
Errno::EHOSTDOWN | 112 | Host is down | - |
Errno::EHOSTUNREACH | 113 | No route to host | - |
Errno::EHWPOISON | 133 | Memory page has hardware error | - |
Errno::EIDRM | 43 | Identifier removed | - |
Errno::EILSEQ | 84 | Invalid or incomplete multibyte or wide character | - |
Errno::EINPROGRESS | 115 | Operation now in progress | - |
Errno::EINPROGRESS → IO::EINPROGRESSWaitReadable² | - | - | - |
Errno::EINPROGRESS → IO::EINPROGRESSWaitWritable² | - | - | - |
Errno::EINTR | 4 | Interrupted system call | - |
Errno::EINVAL | 22 | Invalid argument | Process.clock_gettime(42) |
Errno::EIO | 5 | Input/output error | - |
Errno::EISCONN | 106 | Transport endpoint is already connected | - |
Errno::EISDIR | 21 | Is a directory | File.read("/") |
Errno::EISNAM | 120 | Is a named type file | - |
Errno::EKEYEXPIRED | 127 | Key has expired | - |
Errno::EKEYREJECTED | 129 | Key was rejected by service | - |
Errno::EKEYREVOKED | 128 | Key has been revoked | - |
Errno::EL2HLT | 51 | Level 2 halted | - |
Errno::EL2NSYNC | 45 | Level 2 not synchronized | - |
Errno::EL3HLT | 46 | Level 3 halted | - |
Errno::EL3RST | 47 | Level 3 reset | - |
Errno::ELIBACC | 79 | Can not access a needed shared library | - |
Errno::ELIBBAD | 80 | Accessing a corrupted shared library | - |
Errno::ELIBEXEC | 83 | Cannot exec a shared library directly | - |
Errno::ELIBMAX | 82 | Attempting to link in too many shared libraries | - |
Errno::ELIBSCN | 81 | .lib section in a.out corrupted | - |
Errno::ELNRNG | 48 | Link number out of range | - |
Errno::ELOOP | 40 | Too many levels of symbolic links | - |
Errno::EMEDIUMTYPE | 124 | Wrong medium type | - |
Errno::EMFILE | 24 | Too many open files | - |
Errno::EMLINK | 31 | Too many links | - |
Errno::EMSGSIZE | 90 | Message too long | - |
Errno::EMULTIHOP | 72 | Multihop attempted | - |
Errno::ENAMETOOLONG | 36 | File name too long | File.read("Ruby"*1000) |
Errno::ENAVAIL | 119 | No XENIX semaphores available | - |
Errno::ENETDOWN | 100 | Network is down | - |
Errno::ENETRESET | 102 | Network dropped connection on reset | - |
Errno::ENETUNREACH | 101 | Network is unreachable | - |
Errno::ENFILE | 23 | Too many open files in system | - |
Errno::ENOANO | 55 | No anode | - |
Errno::ENOBUFS | 105 | No buffer space available | - |
Errno::ENOCSI | 50 | No CSI structure available | - |
Errno::ENODATA | 61 | No data available | - |
Errno::ENODEV | 19 | No such device | - |
Errno::ENOENT | 2 | No such file or directory | File.read("does not exist") |
Errno::ENOEXEC | 8 | Exec format error | - |
Errno::ENOKEY | 126 | Required key not available | - |
Errno::ENOLCK | 37 | No locks available | - |
Errno::ENOLINK | 67 | Link has been severed | - |
Errno::ENOMEDIUM | 123 | No medium found | - |
Errno::ENOMEM | 12 | Cannot allocate memory | - |
Errno::ENOMSG | 42 | No message of desired type | - |
Errno::ENONET | 64 | Machine is not on the network | - |
Errno::ENOPKG | 65 | Package not installed | - |
Errno::ENOPROTOOPT | 92 | Protocol not available | - |
Errno::ENOSPC | 28 | No space left on device | - |
Errno::ENOSR | 63 | Out of streams resources | - |
Errno::ENOSTR | 60 | Device not a stream | - |
Errno::ENOSYS | 38 | Function not implemented | - |
Errno::ENOTBLK | 15 | Block device required | - |
Errno::ENOTCONN | 107 | Transport endpoint is not connected | - |
Errno::ENOTDIR | 20 | Not a directory | - |
Errno::ENOTEMPTY | 39 | Directory not empty | - |
Errno::ENOTNAM | 118 | Not a XENIX named type file | - |
Errno::ENOTRECOVERABLE | 131 | State not recoverable | - |
Errno::ENOTSOCK | 88 | Socket operation on non-socket | - |
Errno::ENOTSUP | 95 | Operation not supported | - |
Errno::ENOTTY | 25 | Inappropriate ioctl for device | - |
Errno::ENOTUNIQ | 76 | Name not unique on network | - |
Errno::ENXIO | 6 | No such device or address | - |
Errno::EOPNOTSUPP | 95 | Operation not supported | - |
Errno::EOVERFLOW | 75 | Value too large for defined data type | - |
Errno::EOWNERDEAD | 130 | Owner died | - |
Errno::EPERM | 1 | Operation not permitted | - |
Errno::EPFNOSUPPORT | 96 | Protocol family not supported | - |
Errno::EPIPE | 32 | Broken pipe | - |
Errno::EPROTO | 71 | Protocol error | - |
Errno::EPROTONOSUPPORT | 93 | Protocol not supported | - |
Errno::EPROTOTYPE | 91 | Protocol wrong type for socket | - |
Errno::ERANGE | 34 | Numerical result out of range | - |
Errno::EREMCHG | 78 | Remote address changed | - |
Errno::EREMOTE | 66 | Object is remote | - |
Errno::EREMOTEIO | 121 | Remote I/O error | - |
Errno::ERESTART | 85 | Interrupted system call should be restarted | - |
Errno::ERFKILL | 132 | Operation not possible due to RF-kill | - |
Errno::EROFS | 30 | Read-only file system | - |
Errno::ESHUTDOWN | 108 | Cannot send after transport endpoint shutdown | - |
Errno::ESOCKTNOSUPPORT | 94 | Socket type not supported | - |
Errno::ESPIPE | 29 | Illegal seek | - |
Errno::ESRCH | 3 | No such process | Process.kill(:KILL, 987654321) |
Errno::ESRMNT | 69 | Surmount error | - |
Errno::ESTALE | 116 | Stale file handle | - |
Errno::ESTRPIPE | 86 | Streams pipe error | - |
Errno::ETIME | 62 | Timer expired | - |
Errno::ETIMEDOUT | 110 | Connection timed out | - |
Errno::ETOOMANYREFS | 109 | Too many references: cannot splice | - |
Errno::ETXTBSY | 26 | Text file busy | - |
Errno::EUCLEAN | 117 | Structure needs cleaning | - |
Errno::EUNATCH | 49 | Protocol driver not attached | - |
Errno::EUSERS | 87 | Too many users | - |
Errno::EWOULDBLOCK³ | 11 | Resource temporarily unavailable | - |
Errno::EXDEV | 18 | Invalid cross-device link | - |
Errno::EXFULL | 54 | Exchange full | - |
Errno::NOERROR | 0 | Success | - |
¹ Feel free to suggest more one-liners
² These include IO::WaitReadable
/IO::WaitWritable
. See IO#read_nonblock.
³ EAGAIN == EWOULDBLOCK on most systems
Resources
More Idiosyncratic Ruby
- Please Comment on GitHub
- Next Article: Too Expressive & * _ ?
- Previous Article: Roots of Rubyism