Native 错误处理
游戏程序运行中会出现多种多样的问题,比如网络异常,JavaScript代码错误。
Egret Native 为了开发者方便提供了多种异常处理的接口和方式,本文就讲诉一下。
Egret Native 可以在 原生端
和 javascript端
处理异常
原生端
是指 iOS(Objective-C)/Android(Java) 端。javascript端
是指游戏的javascript执行环境内部。
启动异常
在 index.html 加载时,或者解析 index.html 中的 <script>
标签时,可能会出现文件无法加载的情况。
这一般都会是在 javascript 执行之前,这部分的错误只能由 原生端
处理
原生端
监听 @onError
事件来处理启动异常
- 注册对error事件的监听,请在 native 初始化调用之前注册事件回调
message 为 json 串,属性如下
属性 | 类型 | 说明 |
---|---|---|
error | string | 错误类型 目前 只有 "load" |
url | string | 发生错误的地址 |
code | string | 发生的错误码 |
nativeAndroid.setExternalInterface("@onError", new INativePlayer.INativeInterface() {
@Override
public void callback(String message) {
Log.e(TAG, "Native get onError message: " + message);
}
});
[native setExternalInterface:@"@onError" Callback:^(NSString *message) {
NSLog(@"Get @onError: %@", message);
}];
处理 javascript 运行异常
在 javascript 执行时,可能会由于代码的语法问题、数据的错误、状态的不同步等导致代码执行出错
这样的错误会有如下特点:
- 是 javascript 执行异常:包括语法错误,数组访问越界,null 对象访问等,网络错误不算
- 全局未捕获异常:既没有通过 try catch 捕获。注:异步回调的异常需要单独捕获否则就会产生全局未捕获异常
通过 javascript端
window.onerror
处理
window.onerror = function(message, source, lineno, colno, error) {
console.error("Uncaught", message);
}
原生端
监听 @onJSError
事件来处理启动异常
所有需要 window.onerror
处理的错误,有可能就执行错乱了,所以 汇报到原生端处理,用户无论是否注册了 window.onerror 都会发起
nativeAndroid.setExternalInterface("@onJSError", new INativePlayer.INativeInterface() {
@Override
public void callback(String message) {
Log.e(TAG, "Get @onJSError: " + message);
}
});
[native setExternalInterface:@"@onJSError" Callback:^(NSString *message) {
NSLog(@"Get @onJSError: %@", message);
}];
处理 javascript Promise 异步异常
在使用 Promise
进行异步处理时,可能由于多种情况导致 Promise
被 reject
,在 Promise
被 reject
时 如果不及时进行捕获,则会产生未处理的 reject
即使是 Promise
执行中抛出的 javascript 执行异常,如语法错误,数组访问越界,null 对象访问、也会被作为 reject
而不会触发 window.onerror
这部分异常只能通过 javascript 处理
通过 promise.then 第二个参数处理
promise.then(null, e => {
console.error("Then error (in promise)", e);
});
通过 promise.catch 处理
promise.catch(e => {
console.error("Catch (in promise)", e);
});
通过 window.onunhandledrejection 处理
注意:即使触发了 window.onunhandledrejection 也不是说明 这个 Promise
的 reject
没人处理,可能在之后又有人通过上面的 promise.then 或 promise.catch 处理了这个 Promise
的 reject
。
window.onunhandledrejection(e => {
console.error("Uncaught (in promise)", e);
});
HTML节点错误
HTMLImageElement
, HTMLScriptElement
等HTML节点的加载是通过这些节点的 onerror 处理函数处理
// image 类型
var img = new Image();
img.src = "nothisfile.jpg";
img.onerror = function(e) {
console.error("image load error", e);
}
// script 类型
var script = document.createElement('script');
script.src = "nothisfile.js";
script.onerror = function(e) {
console.error("script load error", e);
}
document.body.appendChild(script);
XMLHttpRequest 请求的错误
如果是网络错误、解析域名、url格式问题等错误,使用 xhr.onerror 处理错误
如果是服务器返回 404 等状态码,不会触发 onerror 事件,需要在代码中通过 xhr.status 判定
var xhr = new XMLHttpRequest();
xhr.open('GET', 'nothisfile.txt', true);
xhr.onerror = function () {
console.error("xhr load error", e);
}
xhr.onload = function () {
console.log("load", xhr.status);
};
例:
白鹭引擎中 manifest.json 的下载是由xhr发起的 用此方案处理