Skip to content

Commit

Permalink
fix(core): support onerror for js
Browse files Browse the repository at this point in the history
  • Loading branch information
etkmao committed Sep 4, 2023
1 parent 7da2c69 commit 300f114
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 29 deletions.
22 changes: 4 additions & 18 deletions driver/js/include/driver/scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,24 +275,7 @@ class Scope : public std::enable_shared_from_this<Scope> {

inline void SetUriLoader(std::weak_ptr<UriLoader> loader) {
loader_ = loader;
auto the_loader = loader_.lock();
if (the_loader) {
the_loader->SetRequestTimePerformanceCallback([WEAK_THIS](const string_view& uri, const TimePoint& start, const TimePoint& end) {
DEFINE_AND_CHECK_SELF(Scope)
auto runner = self->GetTaskRunner();
if (runner) {
auto task = [weak_this, uri, start, end]() {
DEFINE_AND_CHECK_SELF(Scope)
auto entry = self->GetPerformance()->PerformanceResource(uri);
if (entry) {
entry->SetLoadSourceStart(start);
entry->SetLoadSourceEnd(end);
}
};
runner->PostTask(std::move(task));
}
});
}
SetCallbackForUriLoader();
}

inline std::weak_ptr<UriLoader> GetUriLoader() { return loader_; }
Expand Down Expand Up @@ -327,6 +310,8 @@ class Scope : public std::enable_shared_from_this<Scope> {
return performance_;
}

void HandleUriLoaderError(const string_view& uri, const int32_t ret_code, const string_view& error_msg);

#ifdef ENABLE_INSPECTOR
inline void SetDevtoolsDataSource(std::shared_ptr<hippy::devtools::DevtoolsDataSource> devtools_data_source) {
devtools_data_source_ = devtools_data_source;
Expand Down Expand Up @@ -472,6 +457,7 @@ class Scope : public std::enable_shared_from_this<Scope> {
friend class Engine;
void BindModule();
void Bootstrap();
void SetCallbackForUriLoader();

private:
std::weak_ptr<Engine> engine_;
Expand Down
6 changes: 6 additions & 0 deletions driver/js/include/driver/vm/js_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ class VM {
}

static void HandleUncaughtException(const std::shared_ptr<Ctx>& ctx, const std::shared_ptr<CtxValue>& exception);
static void HandleError(const std::shared_ptr<Ctx>& ctx,
const std::shared_ptr<CtxValue>& event,
const std::shared_ptr<CtxValue>& source,
const std::shared_ptr<CtxValue>& lineno,
const std::shared_ptr<CtxValue>& colno,
const std::shared_ptr<CtxValue>& error);
virtual std::shared_ptr<CtxValue> ParseJson(const std::shared_ptr<Ctx>& ctx, const string_view& json) = 0;
virtual std::shared_ptr<Ctx> CreateContext() = 0;
private:
Expand Down
35 changes: 33 additions & 2 deletions driver/js/lib/global/Others.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ global.__GLOBAL__ = {
globalEventHandle: {},
};

class ErrorEvent {
constructor(message, filename, lineno, colno, error) {
this.message = message;
this.filename = filename;
this.lineno = lineno;
this.colno = colno;
this.error = error;
}
}

/**
* Register the Hippy app entry function, the native will trigger an event to execute the function
* and start the app.
Expand Down Expand Up @@ -99,15 +109,33 @@ function emit(eventName, ...args) {
if (typeof eventName !== 'string') {
throw new TypeError('Hippy.emit() only accept a string as event name');
}

let isErr = eventName === 'error';
let errObj = new Error();
if (isErr) {
if (args.length !== 5) {
throw new TypeError('Hippy.emit error only accept 5 params');
}
errObj.message = JSON.stringify(args[4]);
if (Hippy.onerror) {
Hippy.onerror(args[0], args[1], args[2], args[3], errObj);
}
}

const eventListeners = __GLOBAL__.globalEventHandle[eventName];
if (!eventListeners) {
if (eventName === 'uncaughtException' && args[0]) {
if (args[0]) {
console.error(args[0].toString());
}
return;
}
try {
eventListeners.forEach(listener => listener(...args));
if (isErr) {
let event = new ErrorEvent(args[0], args[1], args[2], args[3], errObj);
eventListeners.forEach(listener => listener(event));
} else {
eventListeners.forEach(listener => listener(...args));
}
} catch (err) {
/* eslint-disable-next-line no-console */
console.error(err);
Expand All @@ -122,3 +150,6 @@ Hippy.register = {
Hippy.on = on;
Hippy.off = off;
Hippy.emit = emit;
Hippy.addEventListener = on;
Hippy.removeEventListener = off;
Hippy.onerror = undefined;
28 changes: 28 additions & 0 deletions driver/js/lib/modules/ErrorHandle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2017-2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* 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.
*/

(function errorHandler(event, source, lineno, colno, error) {
if (global.Hippy) {
global.Hippy.emit('error', event, source, lineno, colno, error);
} else {
/* eslint-disable-next-line no-console */
console.error(err);
}
});
3 changes: 2 additions & 1 deletion driver/js/scripts/build-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ function getAllRequiredFiles(platform) {
getAbsolutePath('../lib/bootstrap.js'),
getAbsolutePath(`../lib/entry/${platform}/hippy.js`),
getAbsolutePath('../lib/modules/ExceptionHandle.js'),
getAbsolutePath('../lib/modules/ErrorHandle.js'),
];

rl.on('line', (line) => {
Expand Down Expand Up @@ -241,7 +242,7 @@ function generateCpp(platform, buildDirPath) {
for (let i = 0; i < fileBuffer.length; i += 1) {
byteArr.push(fileBuffer[i]);
}
if (fileName === 'bootstrap' || fileName === 'ExceptionHandle') {
if (fileName === 'bootstrap' || fileName === 'ExceptionHandle' || fileName === 'ErrorHandle') {
code += `
const uint8_t k_${fileName}[] = { ${byteArr.join(',')},0 }; // NOLINT`;
} else {
Expand Down
44 changes: 44 additions & 0 deletions driver/js/src/scope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -599,5 +599,49 @@ void Scope::UnloadInstance(const std::shared_ptr<HippyValue>& value) {
}
}

void Scope::SetCallbackForUriLoader() {
auto the_loader = loader_.lock();
if (the_loader) {
the_loader->SetRequestTimePerformanceCallback([WEAK_THIS](const string_view& uri, const TimePoint& start, const TimePoint& end) {
DEFINE_AND_CHECK_SELF(Scope)
auto runner = self->GetTaskRunner();
if (runner) {
auto task = [weak_this, uri, start, end]() {
DEFINE_AND_CHECK_SELF(Scope)
auto entry = self->GetPerformance()->PerformanceResource(uri);
if (entry) {
entry->SetLoadSourceStart(start);
entry->SetLoadSourceEnd(end);
}
};
runner->PostTask(std::move(task));
}
});
the_loader->SetRequestErrorCallback([WEAK_THIS](const string_view& uri, const int32_t ret_code, const string_view& error_msg) {
DEFINE_AND_CHECK_SELF(Scope)
auto runner = self->GetTaskRunner();
if (runner) {
auto task = [weak_this, uri, ret_code, error_msg]() {
DEFINE_AND_CHECK_SELF(Scope)
self->HandleUriLoaderError(uri, ret_code, error_msg);
};
runner->PostTask(std::move(task));
}
});
}
}

void Scope::HandleUriLoaderError(const string_view& uri, const int32_t ret_code, const string_view& error_msg) {
std::unordered_map<string_view, std::shared_ptr<CtxValue>> error_map;
error_map["code"] = context_->CreateNumber(static_cast<double>(ret_code));
error_map["message"] = context_->CreateString(error_msg);
auto event = context_->CreateString("vfs error");
auto source = context_->CreateString(uri);
auto lineno = context_->CreateNumber(0);
auto colno = context_->CreateNumber(0);
auto error = context_->CreateObject(error_map);
VM::HandleError(context_, event, source, lineno, colno, error);
}

}
}
38 changes: 34 additions & 4 deletions driver/js/src/vm/js_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,23 @@ inline namespace driver {
inline namespace vm {

constexpr char kEventName[] = "uncaughtException";
constexpr char kErrorHandlerJSName[] = "ExceptionHandle.js";
constexpr char kHippyErrorHandlerName[] = "HippyExceptionHandler";
constexpr char kExceptionHandlerJSName[] = "ExceptionHandle.js";
constexpr char kHippyExceptionHandlerName[] = "HippyExceptionHandler";

constexpr char kErrorHandlerJSName[] = "ErrorHandle.js";
constexpr char kHippyErrorHandlerName[] = "HippyErrorHandler";

using Ctx = hippy::Ctx;
using CtxValue = hippy::CtxValue;

void VM::HandleUncaughtException(const std::shared_ptr<Ctx>& ctx,
const std::shared_ptr<CtxValue>& exception) {
auto global_object = ctx->GetGlobalObject();
string_view error_handle_name(kHippyErrorHandlerName);
string_view error_handle_name(kHippyExceptionHandlerName);
auto error_handle_key = ctx->CreateString(error_handle_name);
auto exception_handler = ctx->GetProperty(global_object, error_handle_key);
if (!ctx->IsFunction(exception_handler)) {
const auto& source_code = hippy::GetNativeSourceCode(kErrorHandlerJSName);
const auto& source_code = hippy::GetNativeSourceCode(kExceptionHandlerJSName);
FOOTSTONE_DCHECK(source_code.data_ && source_code.length_);
string_view str_view(source_code.data_, source_code.length_);
exception_handler = ctx->RunScript(str_view, error_handle_name);
Expand All @@ -63,6 +66,33 @@ void VM::HandleUncaughtException(const std::shared_ptr<Ctx>& ctx,
}
}

void VM::HandleError(const std::shared_ptr<Ctx>& ctx,
const std::shared_ptr<CtxValue>& event,
const std::shared_ptr<CtxValue>& source,
const std::shared_ptr<CtxValue>& lineno,
const std::shared_ptr<CtxValue>& colno,
const std::shared_ptr<CtxValue>& error) {
auto global_object = ctx->GetGlobalObject();
string_view error_handle_name(kHippyErrorHandlerName);
auto error_handle_key = ctx->CreateString(error_handle_name);
auto error_handler = ctx->GetProperty(global_object, error_handle_key);
if (!ctx->IsFunction(error_handler)) {
const auto& source_code = hippy::GetNativeSourceCode(kErrorHandlerJSName);
FOOTSTONE_DCHECK(source_code.data_ && source_code.length_);
string_view str_view(source_code.data_, source_code.length_);
error_handler = ctx->RunScript(str_view, error_handle_name);
ctx->SetProperty(global_object, error_handle_key, error_handler);
}

std::shared_ptr<CtxValue> argv[5] = {event, source, lineno, colno, error};

auto try_catch = CreateTryCatchScope(true, ctx);
auto ret_value = ctx->CallFunction(error_handler, ctx->GetGlobalObject(), 5, argv);
if (try_catch->HasCaught()) {
auto message = try_catch->GetExceptionMessage();
FOOTSTONE_LOG(WARNING) << "hippy errorHandler error, description = " << message;
}
}

}
}
Expand Down
Loading

0 comments on commit 300f114

Please sign in to comment.