From afd9b307c318a2559db012ce44fdc4cb1226827f Mon Sep 17 00:00:00 2001 From: Dimitris Dafnis <68849116+jim-daf@users.noreply.github.com> Date: Sun, 26 Apr 2026 11:58:58 +0200 Subject: [PATCH] fix(JsBridge): meaningful error when module or method routing fails (#25) The error path in onCallJsPrompt reported "JBArgument Parse error" for two unrelated failure modes: module not registered and method not exposed. Developers reading the log assumed their JSON was malformed and went looking in the wrong place. This change splits the message into "Module not found" and "Method not found" so the actual cause is visible, and trims the incoming jsonString in JBArgumentParser so a stray whitespace from the prompt channel does not look like a malformed payload. --- .../apkfuns/jsbridge/JBArgumentParser.java | 10 ++++--- .../com/apkfuns/jsbridge/JsBridgeImpl.java | 26 ++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/jsbridge/src/main/java/com/apkfuns/jsbridge/JBArgumentParser.java b/jsbridge/src/main/java/com/apkfuns/jsbridge/JBArgumentParser.java index 97d6873..065f3da 100644 --- a/jsbridge/src/main/java/com/apkfuns/jsbridge/JBArgumentParser.java +++ b/jsbridge/src/main/java/com/apkfuns/jsbridge/JBArgumentParser.java @@ -118,13 +118,17 @@ public void setValue(String value) { @NonNull static JBArgumentParser parse(@Nullable String jsonString) { JBArgumentParser parser = new JBArgumentParser(); - if(TextUtils.isEmpty(jsonString) || (!jsonString.startsWith("{") && - !jsonString.startsWith("["))) { + // Issue #25: trim before the startsWith check so a leading + // whitespace or BOM coming through the prompt channel does + // not look like a malformed payload. + String trimmed = jsonString == null ? null : jsonString.trim(); + if(TextUtils.isEmpty(trimmed) || (!trimmed.startsWith("{") && + !trimmed.startsWith("["))) { parser.setThrowable(new JSONException("Argument error: " + jsonString)); return parser; } try { - JSONObject jsonObject = new JSONObject(jsonString); + JSONObject jsonObject = new JSONObject(trimmed); parser.setId(jsonObject.optLong("id")); parser.setMethod(jsonObject.optString("method")); parser.setModule(jsonObject.optString("module")); diff --git a/jsbridge/src/main/java/com/apkfuns/jsbridge/JsBridgeImpl.java b/jsbridge/src/main/java/com/apkfuns/jsbridge/JsBridgeImpl.java index a4792b1..4a45402 100644 --- a/jsbridge/src/main/java/com/apkfuns/jsbridge/JsBridgeImpl.java +++ b/jsbridge/src/main/java/com/apkfuns/jsbridge/JsBridgeImpl.java @@ -273,10 +273,25 @@ private boolean onCallJsPrompt(String methodArgs, Object result) { if (argumentParser.isSuccess() && !TextUtils.isEmpty(argumentParser.getModule()) && !TextUtils.isEmpty(argumentParser.getMethod())) { JsModule findModule = getModule(argumentParser.getModule()); - if (findModule != null) { - HashMap methodHashMap = exposedMethods.get(findModule); - if (methodHashMap != null && !methodHashMap.isEmpty() && methodHashMap.containsKey( - argumentParser.getMethod())) { + // Issue #25: report routing failures with the actual cause + // instead of a generic "JBArgument Parse error" which makes + // every developer think their JSON is malformed. + if (findModule == null) { + String msg = "Module not found: " + argumentParser.getModule(); + JBLog.e(msg, null); + setJsPromptResult(result, false, msg); + return true; + } + HashMap methodHashMap = exposedMethods.get(findModule); + if (methodHashMap == null || methodHashMap.isEmpty() + || !methodHashMap.containsKey(argumentParser.getMethod())) { + String msg = "Method not found: " + argumentParser.getModule() + + "." + argumentParser.getMethod(); + JBLog.e(msg, null); + setJsPromptResult(result, false, msg); + return true; + } + if (true) { JsMethod method = methodHashMap.get(argumentParser.getMethod()); List parameters = argumentParser.getParameters(); int length = method.getParameterType().size(); @@ -327,9 +342,6 @@ private boolean onCallJsPrompt(String methodArgs, Object result) { } return true; } - } - setJsPromptResult(result, false, "JBArgument Parse error"); - return true; } JBLog.e("JBArgument error", argumentParser.getThrowable()); setJsPromptResult(result, false, argumentParser.getErrorMsg());