• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "uncaught_exception_callback.h"
16 
17 #include <string>
18 
19 #include "js_env_logger.h"
20 #include "native_engine/native_engine.h"
21 #include "ui_content.h"
22 
23 namespace OHOS {
24 namespace JsEnv {
GetNativeStrFromJsTaggedObj(napi_value obj,const char * key)25 std::string NapiUncaughtExceptionCallback::GetNativeStrFromJsTaggedObj(napi_value obj, const char* key)
26 {
27     if (obj == nullptr) {
28         JSENV_LOG_E("Failed to get value from key.");
29         return "";
30     }
31 
32     napi_value valueStr = nullptr;
33     napi_get_named_property(env_, obj, key, &valueStr);
34     napi_valuetype valueType = napi_undefined;
35     napi_typeof(env_, valueStr, &valueType);
36     if (valueType != napi_string) {
37         JSENV_LOG_E("Failed to convert value from key.");
38         return "";
39     }
40 
41     size_t valueStrBufLength = 0;
42     napi_get_value_string_utf8(env_, valueStr, nullptr, 0, &valueStrBufLength);
43     auto valueCStr = std::make_unique<char[]>(valueStrBufLength + 1);
44     size_t valueStrLength = 0;
45     napi_get_value_string_utf8(env_, valueStr, valueCStr.get(), valueStrBufLength + 1, &valueStrLength);
46     std::string ret(valueCStr.get(), valueStrLength);
47     JSENV_LOG_D("GetNativeStrFromJsTaggedObj Success.");
48     return ret;
49 }
50 
operator ()(napi_value obj)51 void NapiUncaughtExceptionCallback::operator()(napi_value obj)
52 {
53     std::string errorMsg = GetNativeStrFromJsTaggedObj(obj, "message");
54     std::string errorName = GetNativeStrFromJsTaggedObj(obj, "name");
55     std::string errorStack = GetNativeStrFromJsTaggedObj(obj, "stack");
56     std::string summary = "Error name:" + errorName + "\n";
57     summary += "Error message:" + errorMsg + "\n";
58     const JsEnv::ErrorObject errorObj = {
59         .name = errorName,
60         .message = errorMsg,
61         .stack = errorStack
62     };
63     bool hasProperty = false;
64     napi_has_named_property(env_, obj, "code", &hasProperty);
65     if (hasProperty) {
66         std::string errorCode = GetNativeStrFromJsTaggedObj(obj, "code");
67         summary += "Error code:" + errorCode + "\n";
68     }
69     if (errorStack.empty()) {
70         JSENV_LOG_E("errorStack is empty");
71         return;
72     }
73     auto errorPos = SourceMap::GetErrorPos(errorStack);
74     std::string error;
75     if (obj != nullptr) {
76         napi_value fuc = nullptr;
77         napi_get_named_property(env_, obj, "errorfunc", &fuc);
78         napi_valuetype valueType = napi_undefined;
79         napi_typeof(env_, fuc, &valueType);
80         if (valueType == napi_function) {
81             error = reinterpret_cast<NativeEngine*>(env_)->GetSourceCodeInfo(fuc, errorPos);
82         }
83     }
84     if (sourceMapOperator_ == nullptr) {
85         JSENV_LOG_E("sourceMapOperator_ is empty");
86         return;
87     }
88     summary += error + "Stacktrace:\n" + sourceMapOperator_->TranslateBySourceMap(errorStack);
89     std::string str = Ace::UIContent::GetCurrentUIStackInfo();
90     if (!str.empty()) {
91         summary.append(str);
92     }
93     if (uncaughtTask_) {
94         uncaughtTask_(summary, errorObj);
95     }
96 }
97 } // namespace JsEnv
98 } // namespace OHOS
99