From 9e14b80e0716c2be71c6100cad7aa7c61ac46c6e Mon Sep 17 00:00:00 2001 From: Gil Date: Tue, 12 Jun 2018 09:36:08 -0700 Subject: Create Status objects from errno (#1374) * Add a portable interface to strerror * Add Status::FromErrno * Add strerror_test.cc to the Xcode project * Use glibc feature selection macros instead of return-type overloads * Fix tensorflow references --- .../core/src/firebase/firestore/util/status.cc | 151 +++++++++++++++++++++ 1 file changed, 151 insertions(+) (limited to 'Firestore/core/src/firebase/firestore/util/status.cc') diff --git a/Firestore/core/src/firebase/firestore/util/status.cc b/Firestore/core/src/firebase/firestore/util/status.cc index 46f3ce6..3e8585a 100644 --- a/Firestore/core/src/firebase/firestore/util/status.cc +++ b/Firestore/core/src/firebase/firestore/util/status.cc @@ -16,6 +16,9 @@ #include "Firestore/core/src/firebase/firestore/util/status.h" +#include + +#include "Firestore/core/src/firebase/firestore/util/strerror.h" #include "Firestore/core/src/firebase/firestore/util/string_format.h" namespace firebase { @@ -29,6 +32,154 @@ Status::Status(FirestoreErrorCode code, absl::string_view msg) { state_->msg = static_cast(msg); } +/// Returns the Canonical error code for the given errno value. +static FirestoreErrorCode CodeForErrno(int errno_code) { + switch (errno_code) { + case 0: + return FirestoreErrorCode::Ok; + + // Internal canonical mappings call these failed preconditions, but for + // our purposes these must indicate an internal error in file handling. + case EBADF: // Invalid file descriptor +#if defined(EBADFD) + case EBADFD: // File descriptor in bad state +#endif + return FirestoreErrorCode::Internal; + + case EINVAL: // Invalid argument + case ENAMETOOLONG: // Filename too long + case E2BIG: // Argument list too long + case EDESTADDRREQ: // Destination address required + case EDOM: // Mathematics argument out of domain of function + case EFAULT: // Bad address + case EILSEQ: // Illegal byte sequence + case ENOPROTOOPT: // Protocol not available + case ENOSTR: // Not a STREAM + case ENOTSOCK: // Not a socket + case ENOTTY: // Inappropriate I/O control operation + case EPROTOTYPE: // Protocol wrong type for socket + case ESPIPE: // Invalid seek + return FirestoreErrorCode::InvalidArgument; + + case ETIMEDOUT: // Connection timed out + case ETIME: // Timer expired + return FirestoreErrorCode::DeadlineExceeded; + + case ENODEV: // No such device + case ENOENT: // No such file or directory +#if defined(ENOMEDIUM) + case ENOMEDIUM: // No medium found +#endif + case ENXIO: // No such device or address + case ESRCH: // No such process + return FirestoreErrorCode::NotFound; + + case EEXIST: // File exists + case EADDRNOTAVAIL: // Address not available + case EALREADY: // Connection already in progress +#if defined(ENOTUNIQ) + case ENOTUNIQ: // Name not unique on network +#endif + return FirestoreErrorCode::AlreadyExists; + + case EPERM: // Operation not permitted + case EACCES: // Permission denied +#if defined(ENOKEY) + case ENOKEY: // Required key not available +#endif + case EROFS: // Read only file system + return FirestoreErrorCode::PermissionDenied; + + case ENOTEMPTY: // Directory not empty + case EISDIR: // Is a directory + case ENOTDIR: // Not a directory + case EADDRINUSE: // Address already in use + case EBUSY: // Device or resource busy + case ECHILD: // No child processes + case EISCONN: // Socket is connected +#if defined(EISNAM) + case EISNAM: // Is a named type file +#endif + case ENOTBLK: // Block device required + case ENOTCONN: // The socket is not connected + case EPIPE: // Broken pipe + case ESHUTDOWN: // Cannot send after transport endpoint shutdown + case ETXTBSY: // Text file busy +#if defined(EUNATCH) + case EUNATCH: // Protocol driver not attached +#endif + return FirestoreErrorCode::FailedPrecondition; + + case ENOSPC: // No space left on device + case EDQUOT: // Disk quota exceeded + case EMFILE: // Too many open files + case EMLINK: // Too many links + case ENFILE: // Too many open files in system + case ENOBUFS: // No buffer space available + case ENODATA: // No message is available on the STREAM read queue + case ENOMEM: // Not enough space + case ENOSR: // No STREAM resources + case EUSERS: // Too many users + return FirestoreErrorCode::ResourceExhausted; + +#if defined(ECHRNG) + case ECHRNG: // Channel number out of range +#endif + case EFBIG: // File too large + case EOVERFLOW: // Value too large to be stored in data type + case ERANGE: // Result too large + return FirestoreErrorCode::OutOfRange; + +#if defined(ENOPKG) + case ENOPKG: // Package not installed +#endif + case ENOSYS: // Function not implemented + case ENOTSUP: // Operation not supported + case EAFNOSUPPORT: // Address family not supported + case EPFNOSUPPORT: // Protocol family not supported + case EPROTONOSUPPORT: // Protocol not supported + case ESOCKTNOSUPPORT: // Socket type not supported + case EXDEV: // Improper link + return FirestoreErrorCode::Unimplemented; + + case EAGAIN: // Resource temporarily unavailable +#if defined(ECOMM) + case ECOMM: // Communication error on send +#endif + case ECONNREFUSED: // Connection refused + case ECONNABORTED: // Connection aborted + case ECONNRESET: // Connection reset + case EINTR: // Interrupted function call + case EHOSTDOWN: // Host is down + case EHOSTUNREACH: // Host is unreachable + case ENETDOWN: // Network is down + case ENETRESET: // Connection aborted by network + case ENETUNREACH: // Network unreachable + case ENOLCK: // No locks available + case ENOLINK: // Link has been severed +#if defined(ENONET) + case ENONET: // Machine is not on the network +#endif + return FirestoreErrorCode::Unavailable; + + case EDEADLK: // Resource deadlock avoided + case ESTALE: // Stale file handle + return FirestoreErrorCode::Aborted; + + case ECANCELED: // Operation cancelled + return FirestoreErrorCode::Cancelled; + + default: { return FirestoreErrorCode::Unknown; } + } +} + +Status Status::FromErrno(int errno_code, absl::string_view msg) { + FirestoreErrorCode canonical_code = CodeForErrno(errno_code); + return Status{canonical_code, + util::StringFormat("%s (errno %s: %s)", msg, errno_code, + StrError(errno_code))}; +} + void Status::Update(const Status& new_status) { if (ok()) { *this = new_status; -- cgit v1.2.3