diff --git a/interfaces/kits/js/src/common/uni_error.cpp b/interfaces/kits/js/src/common/uni_error.cpp index 68db46d2498fb2900d41bc0644fad6ca27386235..35f8db1b4c508b535539f8f05806e648b825ea2f 100644 --- a/interfaces/kits/js/src/common/uni_error.cpp +++ b/interfaces/kits/js/src/common/uni_error.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "log.h" #include "napi/n_val.h" @@ -25,6 +26,18 @@ namespace OHOS { namespace DistributedFS { using namespace std; +static napi_value GenerateBusinessError(napi_env env, int32_t errCode, string errMsg) +{ + napi_value businessError = nullptr; + napi_value code = nullptr; + napi_value msg = nullptr; + code = NVal::CreateInt32(env, errCode).val_; + msg = NVal::CreateUTF8String(env, errMsg).val_; + napi_create_error(env, nullptr, msg, &businessError); + napi_set_named_property(env, businessError, FILEIO_TAG_ERR_CODE.c_str(), code); + return businessError; +} + UniError::UniError() {} UniError::UniError(ELegacy eLegacy) : errno_(eLegacy), codingSystem_(ERR_CODE_SYSTEM_LEGACY) {} @@ -77,7 +90,20 @@ std::string UniError::GetDefaultErrstr() napi_value UniError::GetNapiErr(napi_env env) { - return GetNapiErr(env, GetDefaultErrstr()); + int errCode = GetErrno(codingSystem_); + if (errCode == ERRNO_NOERR) { + return nullptr; + } + int32_t code; + string msg; + if (errCodeTable.find(errCode) != errCodeTable.end()) { + code = errCodeTable.at(errCode).first; + msg = errCodeTable.at(errCode).second; + } else { + code = errCodeTable.at(-1).first; + msg = errCodeTable.at(-1).second; + } + return GenerateBusinessError(env, code, msg); } napi_value UniError::GetNapiErr(napi_env env, string errMsg) @@ -99,16 +125,38 @@ napi_value UniError::GetNapiErr(napi_env env, string errMsg) void UniError::ThrowErr(napi_env env) { - string msg = GetDefaultErrstr(); napi_value tmp = nullptr; napi_get_and_clear_last_exception(env, &tmp); - // Note that ace engine cannot throw errors created by napi_create_error so far - napi_status throwStatus = napi_throw_error(env, nullptr, msg.c_str()); + int32_t code; + string msg; + if (errCodeTable.find(errno_) != errCodeTable.end()) { + code = errCodeTable.at(errno_).first; + msg = errCodeTable.at(errno_).second; + } else { + code = errCodeTable.at(-1).first; + msg = errCodeTable.at(-1).second; + } + napi_status throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg)); if (throwStatus != napi_ok) { HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, msg.c_str()); } } +void UniError::ThrowErr(napi_env env, int code) +{ + napi_value tmp = nullptr; + napi_get_and_clear_last_exception(env, &tmp); + if (errCodeTable.find(code) == errCodeTable.end()) { + code = -1; + } + napi_status throwStatus = napi_throw(env, GenerateBusinessError(env, errCodeTable.at(code).first, + errCodeTable.at(code).second)); + if (throwStatus != napi_ok) { + HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, + errCodeTable.at(code).second.c_str()); + } +} + void UniError::ThrowErr(napi_env env, string errMsg) { napi_value tmp = nullptr; diff --git a/interfaces/kits/js/src/common/uni_error.h b/interfaces/kits/js/src/common/uni_error.h index 883756b73e63f16104e63fc5ba8d1d148b8ea38a..80fdc437c63300817e3710c1ca04b0ea837c137c 100644 --- a/interfaces/kits/js/src/common/uni_error.h +++ b/interfaces/kits/js/src/common/uni_error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,11 +16,16 @@ #ifndef INTERFACES_KITS_JS_SRC_COMMON_UNI_ERROR_H #define INTERFACES_KITS_JS_SRC_COMMON_UNI_ERROR_H +#include +#include + #include "napi/uni_header.h" namespace OHOS { namespace DistributedFS { constexpr int ERRNO_NOERR = 0; +constexpr int FILEIO_SYS_CAP_TAG = 13900000; +const std::string FILEIO_TAG_ERR_CODE = "code"; enum ELegacy { ELEGACY_INVAL = 202, @@ -33,6 +38,96 @@ enum ErrCodeSystem { ERR_CODE_SYSTEM_POSIX, }; +enum ErrCodeSuffix { + E_PERM = 1, + E_NOENT, + E_SRCH, + E_INTR, + E_IO, + E_NXIO, + E_2BIG, + E_BADF, + E_CHILD, + E_AGAIN, + E_NOMEM, + E_ACCES, + E_FAULT, + E_BUSY, + E_EXIST, + E_XDEV, + E_NODEV, + E_NOTDIR, + E_ISDIR, + E_INVAL, + E_NFILE, + E_MFILE, + E_TXTBSY, + E_FBIG, + E_NOSPC, + E_SPIPE, + E_ROFS, + E_MLINK, + E_DEADLK, + E_NAMETOOLONG, + E_NOSYS, + E_NOTEMPTY, + E_LOOP, + E_WOULDBLOCK, + E_BADR, + E_NOSTR, + E_NODATA, + E_OVERFLOW, + E_BADFD, + E_RESTART, + E_DQUOT, + E_UKERR +}; + +const std::unordered_map> errCodeTable { + { EPERM, { FILEIO_SYS_CAP_TAG + E_PERM, "Operation not permitted" } }, + { ENOENT, { FILEIO_SYS_CAP_TAG + E_NOENT, "No such file or directory" } }, + { ESRCH, { FILEIO_SYS_CAP_TAG + E_SRCH, "No such process" } }, + { EINTR, { FILEIO_SYS_CAP_TAG + E_INTR, "Interrupted system call" } }, + { EIO, { FILEIO_SYS_CAP_TAG + E_IO, "I/O error" } }, + { ENXIO, { FILEIO_SYS_CAP_TAG + E_NXIO, "No such device or address" } }, + { E2BIG, { FILEIO_SYS_CAP_TAG + E_2BIG, "Arg list too long" } }, + { EBADF, { FILEIO_SYS_CAP_TAG + E_BADF, "Bad file descriptor" } }, + { ECHILD, { FILEIO_SYS_CAP_TAG + E_CHILD, "No child processes" } }, + { EAGAIN, { FILEIO_SYS_CAP_TAG + E_AGAIN, "Try again" } }, + { ENOMEM, { FILEIO_SYS_CAP_TAG + E_NOMEM, "Out of memory" } }, + { EACCES, { FILEIO_SYS_CAP_TAG + E_ACCES, "Permission denied" } }, + { EFAULT, { FILEIO_SYS_CAP_TAG + E_FAULT, "Bad address" } }, + { EBUSY, { FILEIO_SYS_CAP_TAG + E_BUSY, "Device or resource busy" } }, + { EEXIST, { FILEIO_SYS_CAP_TAG + E_EXIST, "File exists" } }, + { EXDEV, { FILEIO_SYS_CAP_TAG + E_XDEV, "Cross-device link" } }, + { ENODEV, { FILEIO_SYS_CAP_TAG + E_NODEV, "No such device" } }, + { ENOTDIR, { FILEIO_SYS_CAP_TAG + E_NOTDIR, "Not a directory" } }, + { EISDIR, { FILEIO_SYS_CAP_TAG + E_ISDIR, "Is a directory" } }, + { EINVAL, { FILEIO_SYS_CAP_TAG + E_INVAL, "Invalid argument" } }, + { ENFILE, { FILEIO_SYS_CAP_TAG + E_NFILE, "File table overflow" } }, + { EMFILE, { FILEIO_SYS_CAP_TAG + E_MFILE, "Too many open files" } }, + { ETXTBSY, { FILEIO_SYS_CAP_TAG + E_TXTBSY, "Text file busy" } }, + { EFBIG, { FILEIO_SYS_CAP_TAG + E_FBIG, "File too large" } }, + { ENOSPC, { FILEIO_SYS_CAP_TAG + E_NOSPC, "No space left on device" } }, + { ESPIPE, { FILEIO_SYS_CAP_TAG + E_SPIPE, "Illegal seek" } }, + { EROFS, { FILEIO_SYS_CAP_TAG + E_ROFS, "Read-only file system" } }, + { EMLINK, { FILEIO_SYS_CAP_TAG + E_MLINK, "Too many links" } }, + { EDEADLK, { FILEIO_SYS_CAP_TAG + E_DEADLK, "Resource deadlock would occur" } }, + { ENAMETOOLONG, { FILEIO_SYS_CAP_TAG + E_NAMETOOLONG, "File name too long" } }, + { ENOSYS, { FILEIO_SYS_CAP_TAG + E_NOSYS, "Function not implemented" } }, + { ENOTEMPTY, { FILEIO_SYS_CAP_TAG + E_NOTEMPTY, "Directory not empty" } }, + { ELOOP, { FILEIO_SYS_CAP_TAG + E_LOOP, "Too many symbolic links encountered" } }, + { EWOULDBLOCK, { FILEIO_SYS_CAP_TAG + E_WOULDBLOCK, "Operation would block" } }, + { EBADR, { FILEIO_SYS_CAP_TAG + E_BADR, "Invalid request descriptor" } }, + { ENOSTR, { FILEIO_SYS_CAP_TAG + E_NOSTR, "Device not a stream" } }, + { ENODATA, { FILEIO_SYS_CAP_TAG + E_NODATA, "No data available" } }, + { EOVERFLOW, { FILEIO_SYS_CAP_TAG + E_OVERFLOW, "Value too large for defined data type" } }, + { EBADFD, { FILEIO_SYS_CAP_TAG + E_BADFD, "File descriptor in bad state" } }, + { ERESTART, { FILEIO_SYS_CAP_TAG + E_RESTART, "Interrupted system call should be restarted" } }, + { EDQUOT, { FILEIO_SYS_CAP_TAG + E_DQUOT, "Quota exceeded" } }, + { -1, { FILEIO_SYS_CAP_TAG + E_UKERR, "Unknown error" } } +}; + class UniError { public: UniError(); @@ -53,6 +148,7 @@ public: napi_value GetNapiErr(napi_env env); napi_value GetNapiErr(napi_env env, std::string errMsg); void ThrowErr(napi_env env); + void ThrowErr(napi_env env, int code); void ThrowErr(napi_env env, std::string errMsg); private: