Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jesseschalken
Created January 5, 2017 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesseschalken/75652d935f1d1c46700bfd281eb55091 to your computer and use it in GitHub Desktop.
Save jesseschalken/75652d935f1d1c46700bfd281eb55091 to your computer and use it in GitHub Desktop.
<?hh // strict
namespace HackUtils;
final class SystemError extends \RuntimeException {
const int EPERM = 1;
const int ENOENT = 2;
const int ESRCH = 3;
const int EINTR = 4;
const int EIO = 5;
const int ENXIO = 6;
const int E2BIG = 7;
const int ENOEXEC = 8;
const int EBADF = 9;
const int ECHILD = 10;
const int EAGAIN = 11;
const int ENOMEM = 12;
const int EACCES = 13;
const int EFAULT = 14;
const int ENOTBLK = 15;
const int EBUSY = 16;
const int EEXIST = 17;
const int EXDEV = 18;
const int ENODEV = 19;
const int ENOTDIR = 20;
const int EISDIR = 21;
const int EINVAL = 22;
const int ENFILE = 23;
const int EMFILE = 24;
const int ENOTTY = 25;
const int ETXTBSY = 26;
const int EFBIG = 27;
const int ENOSPC = 28;
const int ESPIPE = 29;
const int EROFS = 30;
const int EMLINK = 31;
const int EPIPE = 32;
const int EDOM = 33;
const int ERANGE = 34;
const int EDEADLK = 35;
const int ENAMETOOLONG = 36;
const int ENOLCK = 37;
const int ENOSYS = 38;
const int ENOTEMPTY = 39;
const int ELOOP = 40;
const int ENOMSG = 42;
const int EIDRM = 43;
const int ECHRNG = 44;
const int EL2NSYNC = 45;
const int EL3HLT = 46;
const int EL3RST = 47;
const int ELNRNG = 48;
const int EUNATCH = 49;
const int ENOCSI = 50;
const int EL2HLT = 51;
const int EBADE = 52;
const int EBADR = 53;
const int EXFULL = 54;
const int ENOANO = 55;
const int EBADRQC = 56;
const int EBADSLT = 57;
const int EBFONT = 59;
const int ENOSTR = 60;
const int ENODATA = 61;
const int ETIME = 62;
const int ENOSR = 63;
const int ENONET = 64;
const int ENOPKG = 65;
const int EREMOTE = 66;
const int ENOLINK = 67;
const int EADV = 68;
const int ESRMNT = 69;
const int ECOMM = 70;
const int EPROTO = 71;
const int EMULTIHOP = 72;
const int EDOTDOT = 73;
const int EBADMSG = 74;
const int EOVERFLOW = 75;
const int ENOTUNIQ = 76;
const int EBADFD = 77;
const int EREMCHG = 78;
const int ELIBACC = 79;
const int ELIBBAD = 80;
const int ELIBSCN = 81;
const int ELIBMAX = 82;
const int ELIBEXEC = 83;
const int EILSEQ = 84;
const int ERESTART = 85;
const int ESTRPIPE = 86;
const int EUSERS = 87;
const int ENOTSOCK = 88;
const int EDESTADDRREQ = 89;
const int EMSGSIZE = 90;
const int EPROTOTYPE = 91;
const int ENOPROTOOPT = 92;
const int EPROTONOSUPPORT = 93;
const int ESOCKTNOSUPPORT = 94;
const int EOPNOTSUPP = 95;
const int EPFNOSUPPORT = 96;
const int EAFNOSUPPORT = 97;
const int EADDRINUSE = 98;
const int EADDRNOTAVAIL = 99;
const int ENETDOWN = 100;
const int ENETUNREACH = 101;
const int ENETRESET = 102;
const int ECONNABORTED = 103;
const int ECONNRESET = 104;
const int ENOBUFS = 105;
const int EISCONN = 106;
const int ENOTCONN = 107;
const int ESHUTDOWN = 108;
const int ETOOMANYREFS = 109;
const int ETIMEDOUT = 110;
const int ECONNREFUSED = 111;
const int EHOSTDOWN = 112;
const int EHOSTUNREACH = 113;
const int EALREADY = 114;
const int EINPROGRESS = 115;
const int ESTALE = 116;
const int EUCLEAN = 117;
const int ENOTNAM = 118;
const int ENAVAIL = 119;
const int EISNAM = 120;
const int EREMOTEIO = 121;
const int EDQUOT = 122;
const int ENOMEDIUM = 123;
const int EMEDIUMTYPE = 124;
const int ECANCELED = 125;
const int ENOKEY = 126;
const int EKEYEXPIRED = 127;
const int EKEYREVOKED = 128;
const int EKEYREJECTED = 129;
const int EOWNERDEAD = 130;
const int ENOTRECOVERABLE = 131;
const int ERFKILL = 132;
const int EHWPOISON = 133;
const int EDEADLOCK = self::EDEADLK;
const int EWOULDBLOCK = self::EAGAIN;
private static array<int, string>
$messages = [
self::EPERM => "Operation not permitted",
self::ENOENT => "No such file or directory",
self::ESRCH => "No such process",
self::EINTR => "Interrupted system call",
self::EIO => "Input/output error",
self::ENXIO => "No such device or address",
self::E2BIG => "Argument list too long",
self::ENOEXEC => "Exec format error",
self::EBADF => "Bad file descriptor",
self::ECHILD => "No child processes",
self::EAGAIN => "Resource temporarily unavailable",
self::ENOMEM => "Cannot allocate memory",
self::EACCES => "Permission denied",
self::EFAULT => "Bad address",
self::ENOTBLK => "Block device required",
self::EBUSY => "Device or resource busy",
self::EEXIST => "File exists",
self::EXDEV => "Invalid cross-device link",
self::ENODEV => "No such device",
self::ENOTDIR => "Not a directory",
self::EISDIR => "Is a directory",
self::EINVAL => "Invalid argument",
self::ENFILE => "Too many open files in system",
self::EMFILE => "Too many open files",
self::ENOTTY => "Inappropriate ioctl for device",
self::ETXTBSY => "Text file busy",
self::EFBIG => "File too large",
self::ENOSPC => "No space left on device",
self::ESPIPE => "Illegal seek",
self::EROFS => "Read-only file system",
self::EMLINK => "Too many links",
self::EPIPE => "Broken pipe",
self::EDOM => "Numerical argument out of domain",
self::ERANGE => "Numerical result out of range",
self::EDEADLK => "Resource deadlock avoided",
self::ENAMETOOLONG => "File name too long",
self::ENOLCK => "No locks available",
self::ENOSYS => "Function not implemented",
self::ENOTEMPTY => "Directory not empty",
self::ELOOP => "Too many levels of symbolic links",
self::ENOMSG => "No message of desired type",
self::EIDRM => "Identifier removed",
self::ECHRNG => "Channel number out of range",
self::EL2NSYNC => "Level 2 not synchronized",
self::EL3HLT => "Level 3 halted",
self::EL3RST => "Level 3 reset",
self::ELNRNG => "Link number out of range",
self::EUNATCH => "Protocol driver not attached",
self::ENOCSI => "No CSI structure available",
self::EL2HLT => "Level 2 halted",
self::EBADE => "Invalid exchange",
self::EBADR => "Invalid request descriptor",
self::EXFULL => "Exchange full",
self::ENOANO => "No anode",
self::EBADRQC => "Invalid request code",
self::EBADSLT => "Invalid slot",
self::EBFONT => "Bad font file format",
self::ENOSTR => "Device not a stream",
self::ENODATA => "No data available",
self::ETIME => "Timer expired",
self::ENOSR => "Out of streams resources",
self::ENONET => "Machine is not on the network",
self::ENOPKG => "Package not installed",
self::EREMOTE => "Object is remote",
self::ENOLINK => "Link has been severed",
self::EADV => "Advertise error",
self::ESRMNT => "Srmount error",
self::ECOMM => "Communication error on send",
self::EPROTO => "Protocol error",
self::EMULTIHOP => "Multihop attempted",
self::EDOTDOT => "RFS specific error",
self::EBADMSG => "Bad message",
self::EOVERFLOW => "Value too large for defined data type",
self::ENOTUNIQ => "Name not unique on network",
self::EBADFD => "File descriptor in bad state",
self::EREMCHG => "Remote address changed",
self::ELIBACC => "Can not access a needed shared library",
self::ELIBBAD => "Accessing a corrupted shared library",
self::ELIBSCN => ".lib section in a.out corrupted",
self::ELIBMAX => "Attempting to link in too many shared libraries",
self::ELIBEXEC => "Cannot exec a shared library directly",
self::EILSEQ => "Invalid or incomplete multibyte or wide character",
self::ERESTART => "Interrupted system call should be restarted",
self::ESTRPIPE => "Streams pipe error",
self::EUSERS => "Too many users",
self::ENOTSOCK => "Socket operation on non-socket",
self::EDESTADDRREQ => "Destination address required",
self::EMSGSIZE => "Message too long",
self::EPROTOTYPE => "Protocol wrong type for socket",
self::ENOPROTOOPT => "Protocol not available",
self::EPROTONOSUPPORT => "Protocol not supported",
self::ESOCKTNOSUPPORT => "Socket type not supported",
self::EOPNOTSUPP => "Operation not supported",
self::EPFNOSUPPORT => "Protocol family not supported",
self::EAFNOSUPPORT => "Address family not supported by protocol",
self::EADDRINUSE => "Address already in use",
self::EADDRNOTAVAIL => "Cannot assign requested address",
self::ENETDOWN => "Network is down",
self::ENETUNREACH => "Network is unreachable",
self::ENETRESET => "Network dropped connection on reset",
self::ECONNABORTED => "Software caused connection abort",
self::ECONNRESET => "Connection reset by peer",
self::ENOBUFS => "No buffer space available",
self::EISCONN => "Transport endpoint is already connected",
self::ENOTCONN => "Transport endpoint is not connected",
self::ESHUTDOWN => "Cannot send after transport endpoint shutdown",
self::ETOOMANYREFS => "Too many references: cannot splice",
self::ETIMEDOUT => "Connection timed out",
self::ECONNREFUSED => "Connection refused",
self::EHOSTDOWN => "Host is down",
self::EHOSTUNREACH => "No route to host",
self::EALREADY => "Operation already in progress",
self::EINPROGRESS => "Operation now in progress",
self::ESTALE => "Stale file handle",
self::EUCLEAN => "Structure needs cleaning",
self::ENOTNAM => "Not a XENIX named type file",
self::ENAVAIL => "No XENIX semaphores available",
self::EISNAM => "Is a named type file",
self::EREMOTEIO => "Remote I/O error",
self::EDQUOT => "Disk quota exceeded",
self::ENOMEDIUM => "No medium found",
self::EMEDIUMTYPE => "Wrong medium type",
self::ECANCELED => "Operation canceled",
self::ENOKEY => "Required key not available",
self::EKEYEXPIRED => "Key has expired",
self::EKEYREVOKED => "Key has been revoked",
self::EKEYREJECTED => "Key was rejected by service",
self::EOWNERDEAD => "Owner died",
self::ENOTRECOVERABLE => "State not recoverable",
self::ERFKILL => "Operation not possible due to RF-kill",
self::EHWPOISON => "Memory page has hardware error",
];
private static ?array<string, int> $codes;
public static function fromPhpError(\ErrorException $e): \Exception {
$message = $e->getMessage();
// Remove the prefix from errors in format like
// "mkdir(): No such file or directory"
$split = split($message, '(): ', 2);
if (count($split) >= 2)
$message = $split[1];
$code = self::codeFromMessage($message);
if ($code !== null)
return new self($code, $e);
return $e;
}
private static function codeFromMessage(string $message): ?int {
$codes =
self::$codes !== null
? self::$codes
: (self::$codes = keys_to_lower(flip(self::$messages)));
return get_or_null($codes, to_lower(trim($message)));
}
public function __construct(int $code, ?\Exception $prev = null) {
parent::__construct(self::$messages[$code], $code, $prev);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment