Skip to content

Commit

Permalink
JS异常统一回调 (#467)
Browse files Browse the repository at this point in the history
* JS异常统一回调

* add comments
  • Loading branch information
biezhihua authored Dec 13, 2023
1 parent 4d63905 commit e8bfb1e
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ public WebSocketImpl(WebSocketListener listener, Draft draft) {
*/
public void decode(ByteBuffer socketBuffer) {
assert (socketBuffer.hasRemaining());
Log.e("[GaiaX]", "process({}): ({})");

if (readyState != ReadyState.NOT_YET_CONNECTED) {
if (readyState == ReadyState.OPEN) {
Expand Down Expand Up @@ -384,7 +383,6 @@ private void decodeFrames(ByteBuffer socketBuffer) {
try {
frames = draft.translateFrame(socketBuffer);
for (Framedata f : frames) {
Log.e("[GaiaX]", "matched frame: {}");
draft.processFrame(this, f);
}
} catch (LimitExceededException e) {
Expand Down Expand Up @@ -641,7 +639,6 @@ private void send(Collection<Framedata> frames) {
}
ArrayList<ByteBuffer> outgoingFrames = new ArrayList<ByteBuffer>();
for (Framedata f : frames) {
Log.e("[GaiaX]", "send frame: {}");
outgoingFrames.add(draft.createBinaryFrame(f));
}
write(outgoingFrames);
Expand Down Expand Up @@ -698,8 +695,6 @@ public void startHandshake(ClientHandshakeBuilder handshakedata) throws InvalidH
}

private void write(ByteBuffer buf) {
Log.e("[GaiaX]", "write({}): {}");

outQueue.add(buf);
wsl.onWriteDemand(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.alibaba.fastjson.JSONObject
import com.alibaba.gaiax.GXTemplateEngine
import com.alibaba.gaiax.demo.R
import com.alibaba.gaiax.demo.source.GXFastPreviewSource
import com.alibaba.gaiax.js.GXJSEngine
import com.alibaba.gaiax.js.proxy.GXJSEngineProxy
import com.alibaba.gaiax.studio.GXStudioClient
import com.alibaba.gaiax.template.GXSize.Companion.dpToPx
Expand Down Expand Up @@ -139,6 +140,15 @@ class GXFastPreviewActivity : AppCompatActivity(), GXStudioClient.IFastPreviewLi
// 获取模板信息
val gxTemplateInfo = GXTemplateEngine.instance.getGXTemplateInfo(gxTemplateItem)
if (gxTemplateInfo.isJsExist) {

// 设置JS异常监听
GXJSEngineProxy.instance.jsExceptionListener =
object : GXJSEngine.IJsExceptionListener {
override fun exception(data: JSONObject) {
Log.d(TAG, "exception() called with: data = $data")
}
}

// 注册容器
GXJSEngineProxy.instance.registerComponentAndOnReady(gxView)
}
Expand Down
25 changes: 25 additions & 0 deletions GaiaXAndroidJS/src/main/kotlin/com/alibaba/gaiax/js/GXJSEngine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class GXJSEngine {
*/
internal var logListener: ILogListener? = null

/**
* JS内抛出的错误
*/
internal var jsExceptionListener: IJsExceptionListener? = null

/**
* app的Context
*/
Expand Down Expand Up @@ -73,6 +78,11 @@ class GXJSEngine {
return this
}

fun setJSExceptionListener(listener: IJsExceptionListener): GXJSEngine {
this.jsExceptionListener = listener;
return this
}

private fun initModules() {
try {
registerInnerModules()
Expand Down Expand Up @@ -373,6 +383,21 @@ class GXJSEngine {
}
}

interface IJsExceptionListener {

/**
* 当JS执行发生异常时调用
* {
* "templateId":"test",
* "templateVersion":-1,
* "bizId":"fastpreview",
* "message":"'data' is not defined",
* "stack":" at onReady ()\n at call (native)\n at <anonymous> ()\n at <anonymous> (:5)\n at <anonymous> (:7)\n"
* }
*/
fun exception(data: JSONObject)
}

interface ILogListener {
fun errorLog(data: JSONObject)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ internal class QuickJSRuntime private constructor(val runtime: GXHostRuntime, va

// 设置Promise方法的异常兜底回调
jsRuntime?.setPromiseRejectionHandler { message ->

if (Log.isLog()) {
Log.e("setPromiseRejectionHandler() called with: message = $message")
}

GXJSEngine.instance.logListener?.errorLog(JSONObject().apply {
this["data"] = JSONObject().apply {
this["message"] = message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.alibaba.gaiax.js.api.IGXCallback
import com.alibaba.gaiax.js.api.IGXPromise
import com.alibaba.gaiax.js.engine.GXHostContext
import com.alibaba.gaiax.js.support.JSDataConvert
import com.alibaba.gaiax.js.utils.GXJSUiExecutor
import com.alibaba.gaiax.js.utils.Log
import com.alibaba.gaiax.quickjs.BridgeModuleListener
import com.alibaba.gaiax.quickjs.JSContext
Expand All @@ -27,6 +28,23 @@ internal class QuickJSBridgeModule(
val methodId = target.getLongValue("methodId")
val args = target.getJSONArray("args")

// 处理异常 当args.data.stack存在时,说明是JS异常
// {"moduleId":5,"methodId":22,"timestamp":788306541,"args":[{"data":{"templateId":"test","templateVersion":-1,"bizId":"fastpreview","message":"'data' is not defined","stack":" at onReady ()\n at call (native)\n at <anonymous> ()\n at <anonymous> (:5)\n at <anonymous> (:7)\n"}}],"contextId":9}
if (args.size >= 1 && args[0] is JSONObject) {
args.getJSONObject(0)?.let { it ->
it.getJSONObject("data")?.let {
if (it.containsKey("stack")) {
GXJSUiExecutor.action {
GXJSEngine.instance.jsExceptionListener?.exception(it)
}
val jsValue = JSDataConvert.convertToJSValue(jsContext, jsContext.createJSNull().pointer)
return jsValue.pointer
}
}
}
}

//
val result = hostContext.bridge.callSync(contextId, moduleId, methodId, args)
?: jsContext.createJSNull().pointer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class GXJSEngineProxy {
return GXJSEngine.instance.getSocketBridge()
}

var jsExceptionListener: GXJSEngine.IJsExceptionListener? = null

fun init(context: Context) {

// 初始化JS引擎
Expand All @@ -77,6 +79,22 @@ class GXJSEngineProxy {
if (Log.isLog()) {
Log.d("errorLog() called with: data = $data")
}
GXJSEngine.instance.getSocketSender()?.let {
GXJSLogModule.sendJSLogMsg("error", data.toJSONString())
}
}
})

// 设置异常监听器
GXJSEngine.instance.setJSExceptionListener(object : GXJSEngine.IJsExceptionListener {
override fun exception(data: JSONObject) {
if (Log.isLog()) {
Log.d("exception() called with: data = $data")
}
jsExceptionListener?.exception(data)
GXJSEngine.instance.getSocketSender()?.let {
GXJSLogModule.sendJSLogMsg("error", data.toJSONString())
}
}
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import com.alibaba.gaiax.js.GXJSEngine
import com.alibaba.gaiax.js.api.GXJSBaseModule
import com.alibaba.gaiax.js.api.annotation.GXSyncMethod



@Keep
class GXJSLogModule : GXJSBaseModule() {

Expand All @@ -19,7 +21,7 @@ class GXJSLogModule : GXJSBaseModule() {
"${e.message}"
}

private fun sendJSLogMsg(level: String, msg: String) {
fun sendJSLogMsg(level: String, msg: String) {
val data = JSONObject()
data["jsonrpc"] = "2.0"
data["method"] = "js/console"
Expand All @@ -45,28 +47,28 @@ class GXJSLogModule : GXJSBaseModule() {
fun log(data: String) {
val msg = getLogMsg(data)
sendJSLogMsg("log", msg)
Log.d(TAG, "log:msg = $msg")
Log.d(TAG, "jslog:msg = $msg")
}

@GXSyncMethod
fun info(data: String) {
val msg = getLogMsg(data)
sendJSLogMsg("info", msg)
Log.i(TAG, "log:msg = $msg")
Log.i(TAG, "jslog:msg = $msg")
}

@GXSyncMethod
fun warn(data: String) {
val msg = getLogMsg(data)
sendJSLogMsg("warn", msg)
Log.w(TAG, "log:msg = $msg")
Log.w(TAG, "jslog:msg = $msg")
}

@GXSyncMethod
fun error(data: String) {
val msg = getLogMsg(data)
sendJSLogMsg("error", msg)
Log.e(TAG, "log:msg = $msg")
Log.e(TAG, "jslog:msg = $msg")
}

override val name: String
Expand Down
2 changes: 2 additions & 0 deletions GaiaXJSiOS/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Podfile.lock
.DS_Store

xcuserdata/

xcshareddata/

0 comments on commit e8bfb1e

Please sign in to comment.