* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "napi_error.h"
#include "medialibrary_client_errno.h"
#include "medialibrary_napi_utils.h"
using namespace std;
namespace OHOS {
namespace Media {
static std::string GetSpecificErrorMessage(int32_t err, const char *funcName)
{
if (err != JS_INNER_FAIL) {
return "";
}
if (funcName == nullptr) {
return "";
}
std::string func(funcName);
if (func.find("Constructor") != std::string::npos ||
func.find("_constructor") != std::string::npos) {
return "Failed to create object.";
}
if (func.find("Get") != std::string::npos) {
if (func.find("Count") != std::string::npos) {
return "Failed to get count.";
}
if (func.find("Type") != std::string::npos) {
return "Failed to get type.";
}
return "Failed to get value.";
}
if (func.find("Set") != std::string::npos) {
return "Failed to set value.";
}
if (func.find("Create") != std::string::npos) {
return "Failed to create Object.";
}
if (func.find("UnWrap") != std::string::npos) {
return "Failed to unwrap Object.";
}
if (func.find("Array") != std::string::npos) {
return "Failed to process array.";
}
if (func.find("CallBack") != std::string::npos) {
return "Failed to process CallBack.";
}
if (func.find("Init") != std::string::npos) {
return "Failed to process CallBack.";
}
return "";
}
void NapiError::SetApiName(const std::string &Name)
{
apiName = Name;
}
void NapiError::SaveError(const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
error = MediaLibraryNapiUtils::TransErrorCode(apiName, resultSet);
}
void NapiError::SaveError(int32_t ret)
{
if (ret < 0) {
error = MediaLibraryNapiUtils::TransErrorCode(apiName, ret);
if (error == JS_E_FILE_EXTENSION) {
if (ret == E_CHECK_MEDIATYPE_MATCH_EXTENSION_FAIL) {
errorMsg = "File extension does not match the media type";
} else if (ret == E_CHECK_MEDIATYPE_FAIL) {
errorMsg = "Media type does not match relative path";
} else if (ret == E_CHECK_EXTENSION_FAIL) {
errorMsg = "File extension does not match directory type";
}
} else if (error == JS_INNER_FAIL) {
if (ret == E_FILE_OPER_FAIL) {
errorMsg = "File operation failed";
}
}
}
}
void NapiError::SaveRealErr(int32_t ret)
{
if (ret < 0) {
realErr = MediaLibraryNapiUtils::TransErrorCode(apiName, ret);
if (realErr == JS_E_FILE_EXTENSION && errorMsg.empty()) {
if (ret == E_CHECK_MEDIATYPE_MATCH_EXTENSION_FAIL) {
errorMsg = "File extension does not match the media type";
} else if (ret == E_CHECK_MEDIATYPE_FAIL) {
errorMsg = "Media type does not match relative path";
} else if (ret == E_CHECK_EXTENSION_FAIL) {
errorMsg = "File extension does not match directory type";
}
} else if (realErr == JS_INNER_FAIL && errorMsg.empty()) {
if (ret == E_FILE_OPER_FAIL) {
errorMsg = "File operation failed";
}
}
}
NAPI_ERR_LOG("SaveRealErr errCode:%{public}d realErr:%{public}d", ret, realErr);
}
void NapiError::SaveSceneErr(int32_t ret)
{
if (ret < 0) {
error = MediaLibraryNapiUtils::TransErrorCode(apiName, ret);
if (ret == E_SCENE_HAS_DELETED) {
errorMsg = "1.The asset to be copied has been deleted";
} else if (ret == E_SCENE_IS_HIDDEN) {
errorMsg = "2.The asset to be copied is hidden";
} else if (ret == E_SCENE_IS_CLOUD) {
errorMsg = "3.The asset to be copied is a pure cloud image and does not support copying";
} else if (ret == E_SCENE_ALBUM_NOT_EXIST) {
errorMsg = "4.The target album does not exist";
} else if (ret == E_SCENE_NO_ENOUGH_SPACE) {
errorMsg = "5.Not enough space";
} else if (ret == E_SCENE_HAS_RENAMED) {
errorMsg = "6.Renaming files is not supported";
} else if (ret == E_SCENE_HAS_CANCEL) {
errorMsg = "7.Operation cancelled";
} else {
errorMsg = "File operation failed";
}
}
NAPI_ERR_LOG("SaveSceneErr errCode:%{public}d error:%{public}d", ret, error);
}
void NapiError::SaveMoveError(int32_t ret)
{
if (ret < 0) {
error = MediaLibraryNapiUtils::TransMoveErrorCode(apiName, ret);
if (error == JS_E_PARAM_INVALID) {
if (ret == E_PATH_NOT_SUPPORT) {
errorMsg = "Path not supported.";
} else if (ret == E_FILE_NOT_EXIST) {
errorMsg = "File does not exist.";
} else if (ret == E_RENAME) {
errorMsg = "File with the same name already exists.";
} else if (ret == E_MEDIA_TYPE_INVAILD) {
errorMsg = "File type is not supported.";
} else if (ret == E_CANCEL_TASK) {
errorMsg = "Task has been canceled.";
} else if (ret == E_TARGET_ALBUM_INVAILD) {
errorMsg = "Target album does not exist.";
} else if (ret == E_FILE_HIDDEN_OR_TRASHED) {
errorMsg = "File has been hidden or trashed.";
} else if (ret == E_FILE_IS_PENDING_STATU) {
errorMsg = "File is in pending status.";
}
}
}
NAPI_ERR_LOG("SaveMoveErr errCode:%{public}d error:%{public}d", ret, error);
}
void NapiError::HandleError(napi_env env, napi_value &errorObj, bool isIntCode)
{
if (isIntCode) {
AsyncErrorInfo errInfo = { error, realErr, apiName, errorMsg };
MediaLibraryNapiUtils::HandleErrorWithIntCode(env, errorObj, errInfo);
} else {
MediaLibraryNapiUtils::HandleError(env, error, errorObj, apiName, realErr, errorMsg);
}
}
void NapiError::ThrowErrorWithIntCode(napi_env env, int32_t errCode, const std::string &errMsg)
{
string message = errMsg;
if (message.empty()) {
message = "operation not support";
if (jsErrMap.count(errCode) > 0) {
message = jsErrMap.at(errCode);
}
}
NAPI_DEBUG_LOG("ThrowError errCode:%{public}d errMsg:%{public}s", errCode, message.c_str());
napi_value napiMessage = nullptr;
napi_value code = nullptr;
napi_value result = nullptr;
napi_create_string_utf8(env, message.c_str(), NAPI_AUTO_LENGTH, &napiMessage);
napi_create_error(env, nullptr, napiMessage, &result);
napi_create_int32(env, errCode, &code);
napi_set_named_property(env, result, "code", code);
NAPI_CALL_RETURN_VOID(env, napi_throw(env, result));
}
void NapiError::ThrowErrorWithIntCode(napi_env env, int32_t errCode, const char *funcName, int32_t line,
const std::string &errMsg)
{
string message = errMsg;
if (errCode == JS_E_INNER_FAIL) {
std::string combineMsg = jsErrMap.count(errCode) > 0 ? jsErrMap.at(errCode) : "operation not support";
if (!message.empty()) {
message = combineMsg + ":" + message;
}
}
if (message.empty()) {
message = "operation not support";
if (jsErrMap.count(errCode) > 0) {
message = jsErrMap.at(errCode);
}
if (errCode == JS_INNER_FAIL) {
std::string specificMsg = GetSpecificErrorMessage(errCode, funcName);
if (!specificMsg.empty()) {
message = message + ", " + specificMsg;
}
}
}
NAPI_ERR_LOG("{%{public}s:%d} ThrowError errCode:%{public}d errMsg:%{public}s", funcName, line,
errCode, message.c_str());
ThrowErrorWithIntCode(env, errCode, message);
}
void NapiError::ThrowError(napi_env env, int32_t err, const std::string &errMsg)
{
string message = errMsg;
if (message.empty()) {
message = "operation not support";
if (jsErrMap.count(err) > 0) {
message = jsErrMap.at(err);
}
}
NAPI_DEBUG_LOG("ThrowError errCode:%{public}d errMsg:%{public}s", err, message.c_str());
NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str()));
}
void NapiError::ThrowError(napi_env env, int32_t err, const char *funcName, int32_t line, const std::string &errMsg)
{
string message = errMsg;
if (err == JS_E_INNER_FAIL) {
std::string combineMsg = jsErrMap.count(err) > 0 ? jsErrMap.at(err) : "operation not support";
if (!message.empty()) {
message = combineMsg + ":" + message;
}
}
if (message.empty()) {
message = "operation not support";
if (jsErrMap.count(err) > 0) {
message = jsErrMap.at(err);
}
if (err == JS_INNER_FAIL) {
std::string specificMsg = GetSpecificErrorMessage(err, funcName);
if (!specificMsg.empty()) {
message = message + ", " + specificMsg;
}
}
}
NAPI_ERR_LOG("{%{public}s:%d} ThrowError errCode:%{public}d errMsg:%{public}s", funcName, line,
err, message.c_str());
NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, to_string(err).c_str(), message.c_str()));
}
}
}