Skip to content

Commit

Permalink
ZK-5135: Make a client error more helpful for debug
Browse files Browse the repository at this point in the history
  • Loading branch information
rebecca0201 committed Jan 16, 2024
1 parent 702639c commit 7bab971
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 8 deletions.
2 changes: 2 additions & 0 deletions zk/src/main/java/org/zkoss/zk/ui/http/WpdExtendlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,8 @@ else if (WebApps.getFeature("pe"))
sb.append("ta:1,");
if (config.isDebugJS())
sb.append("dj:1,");
if (config.isSendClientErrors())
sb.append("sce:1,");
if (config.isKeepDesktopAcrossVisits())
sb.append("kd:1,");
if (config.getPerformanceMeter() != null)
Expand Down
2 changes: 1 addition & 1 deletion zk/src/main/java/org/zkoss/zk/ui/impl/DesktopImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ public void service(AuRequest request, boolean everError) {
} else if ("error".equals(cmd)) {
final Map<String, Object> data = request.getData();
if (data != null)
log.error(this + " client error: " + data.get("message"));
log.error("Client encountered an error at {}:\n{}", data.get("href"), data.get("message"));
} else if ("fallbackServerPushClass".equals(cmd)) {
try {
getDevice().setServerPushClass(Classes.forNameByThread("org.zkoss.zkex.ui.comet.CometServerPush"));
Expand Down
6 changes: 6 additions & 0 deletions zk/src/main/java/org/zkoss/zk/ui/sys/ConfigParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ else if ("listener".equals(elnm)) {
// resend-delay
// debug-js
// enable-source-map
// send-client-errors
// auto-resend-timeout
parseClientConfig(config, el);

Expand Down Expand Up @@ -766,6 +767,11 @@ private static void parseClientConfig(Configuration config, Element conf) {
if (s != null)
config.enableSourceMap(!"false".equals(s));

//F100-ZK-5135: add new config for whether to send client errors to the server
s = conf.getElementValue("send-client-errors", true);
if (s != null)
config.setSendClientErrors(!"false".equals(s));

//F70-ZK-2495: add new config to customize crash script
s = conf.getElementValue("init-crash-script", true);
if (s != null)
Expand Down
18 changes: 18 additions & 0 deletions zk/src/main/java/org/zkoss/zk/ui/util/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public class Configuration {

private boolean _sourceMapEnabled = false;
private boolean _historyStateEnabled = true;
private boolean _sendClientErrors = false;

/** Constructor.
*/
Expand Down Expand Up @@ -3265,4 +3266,21 @@ public boolean isHistoryStateEnabled() {
return _historyStateEnabled;
}

/**
* Sets whether to send client errors to the server.
* <p>Default: false.</p>
* @since 10.0.0
*/
public void setSendClientErrors(boolean send) {
_sendClientErrors = send;
}

/**
* Returns whether to send client errors to the server.
* <p>Default: false.</p>
* @since 10.0.0
*/
public boolean isSendClientErrors() {
return _sendClientErrors;
}
}
1 change: 1 addition & 0 deletions zk/src/main/resources/web/js/zk/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7171,6 +7171,7 @@ export namespace widget_global {
case 'td': zk.tipDelay = val as number; break;
case 'art': zk.resendTimeout = val as number; break;
case 'dj': zk.debugJS = val as boolean; break;
case 'sce': zk.sendClientErrors = val as boolean; break;
case 'kd': zk.keepDesktop = val as boolean; break;
case 'pf': zk.pfmeter = val as boolean; break;
case 'ta': zk.timerAlive = val as boolean; break;
Expand Down
29 changes: 25 additions & 4 deletions zk/src/main/resources/web/js/zk/zk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1197,17 +1197,23 @@ _zk._noESC = 0; //# of disableESC being called (also used by mount.js)
* ```ts
* zk.error('Oops! Something wrong:(');
* ```
* @param msg - the error message
* @param err - the error or error message
* @param silent - only show error box
* @see {@link errorPush}
* @see {@link errorDismiss}
* @see {@link log}
* @see {@link stamp}
*/
_zk.error = function (msg: string, silent?: boolean): void {
_zk.error = function (err: Error | string, silent?: boolean): void {
const msg = err instanceof Error ? err.message : err,
stack = err instanceof Error ? err.stack : undefined;
if (!silent) {
zAu.send(new zk.Event(zk.Desktop._dt, 'error', {message: msg}, {ignorable: true}), 800);
if (stack)
_zk.debugLog(stack);
if (_zk.sendClientErrors)
zAu.send(new zk.Event(zk.Desktop._dt, 'error', {href: document.location.href, message: stack ?? msg}, {ignorable: true}), 800);
}
_zk._Erbx.push(msg);
_zk.errorPush(msg);
};
//DEBUG//
/**
Expand All @@ -1222,6 +1228,19 @@ _zk.error = function (msg: string, silent?: boolean): void {
_zk.debugLog = function (msg: string): void {
if (_zk.debugJS) console.log(msg); // eslint-disable-line no-console
};
/**
* Push an error message to the error box.
* Example:
* ```ts
* zk.errorPush('Oops! Something wrong:(');
* ```
* @param msg - the error message
* @see {@link zk.error}
* @since 10.0.0
*/
_zk.errorPush = function (msg: string): void {
_zk._Erbx.push(msg);
};
/** Closes all error messages shown by {@link error}.
* Example:
* ```ts
Expand Down Expand Up @@ -2154,6 +2173,8 @@ declare namespace _zk {
export let processMask: boolean | undefined;
// eslint-disable-next-line zk/preferStrictBooleanType
export let debugJS: boolean | undefined;
// eslint-disable-next-line zk/preferStrictBooleanType
export let sendClientErrors: boolean | undefined;
export let updateURI: string | undefined;
export let resourceURI: string | undefined;
export let contextURI: string | undefined;
Expand Down
5 changes: 3 additions & 2 deletions zkdoc/release-note
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ZK 10.0.0
ZK-5512: Support for Listening to Space Key Pressed
ZK-5096: Consider deprecate Anchorlayout and Anchorchildren
ZK-4988: zEmbedded support for websocket
ZK-5135: Make a client error more helpful for debug

* Bugs
ZK-5393: Update ZK jars to jakarta-friendly uploads
Expand Down Expand Up @@ -41,8 +42,8 @@ ZK 10.0.0
simplifying the source to enable embedded mode.
+ The setContent() method of Comboitem, Menu, and Navitem now only accepts a safe HTML content.
i.e. The content will be sanitized before rendering, please don't use JavaScript content.
+ When multiple zEmbedded components with WebSocket enabled are present on a page,
the WebSocket endpoint of the last loaded zEmbedded component will be used.
+ zEmbedded supports WebSocket under the condition that only one ZK page can be embedded into a non-ZK page
when WebSocket is enabled.
--------
ZK 10.0.0-Beta
Oct 17, 2023
Expand Down
1 change: 1 addition & 0 deletions zktest/src/main/webapp/WEB-INF/zk.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Copyright (C) 2006 Potix Corporation. All Rights Reserved.
<client-config>
<debug-js>true</debug-js>
<enable-source-map>false</enable-source-map> <!-- default: false -->
<send-client-errors>false</send-client-errors> <!-- default: false -->
</client-config>

<!-- Uncomment if you turn off the caching of resources loaded from
Expand Down
7 changes: 7 additions & 0 deletions zktest/src/main/webapp/test2/F100-ZK-5135-zk.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<zk>
<client-config>
<debug-js>true</debug-js>
<send-client-errors>true</send-client-errors>
</client-config>
</zk>
32 changes: 32 additions & 0 deletions zktest/src/main/webapp/test2/F100-ZK-5135.zul
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
F100-ZK-5135.zul
Purpose:
Description:
History:
Fri Jan 12 14:53:31 CST 2024, Created by rebeccalai
Copyright (C) 2024 Potix Corporation. All Rights Reserved.
-->
<zk>
<label multiline="true">
1. enable debug-js and send-client-errors with
<client-config>
<debug-js>true</debug-js>
<send-client-errors>true</send-client-errors>
</client-config>
2. should see 'custom error message' in the error box, else override zk.errorPush not working.
3. should see error stack trace in the browser console and the server log.
</label>
<script><![CDATA[
zk.afterLoad('zk', function () {
zk.errorPush = function (msg) {
zk._Erbx.push('custom error message');
};
});
]]></script>
<textbox constraint="//aab\o/"/>
</zk>
1 change: 1 addition & 0 deletions zktest/src/main/webapp/test2/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3743,6 +3743,7 @@ F86-ZK-4235.zul=A,E,datefmt,library-property
##manually##F100-ZK-5048.zul=A,E,MVVM,DebuggerFactory,Log
##zats##F100-ZK-5512.zul=A,E,CtrlKeys,Space
#manually##F100-ZK-4988.html=A,E,Embedded,WebSocket
##zats##F100-ZK-5135.zul=A,E,debugJS,sendClientErrors

# Complex Test Case
#
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* F100_ZK_5135Test.java
Purpose:
Description:
History:
Mon Jan 15 17:01:07 CST 2024, Created by rebeccalai
Copyright (C) 2024 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zktest.zats.test2;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.openqa.selenium.logging.LogType;
import org.slf4j.Logger;

import org.zkoss.test.webdriver.ExternalZkXml;
import org.zkoss.test.webdriver.ForkJVMTestOnly;
import org.zkoss.test.webdriver.WebDriverTestCase;
import org.zkoss.zk.ui.impl.DesktopImpl;

@ForkJVMTestOnly
public class F100_ZK_5135Test extends WebDriverTestCase {
@RegisterExtension
public static final ExternalZkXml CONFIG = new ExternalZkXml("/test2/F100-ZK-5135-zk.xml");

@Test
public void test() throws Exception {
Logger logger = mock(Logger.class);
setFinalStatic(DesktopImpl.class.getDeclaredField("log"), logger);
connect();
waitResponse();
assertTrue(jq(".z-error").text().contains("custom error message"));
// check browser log
driver.manage().logs().get(LogType.BROWSER).getAll().stream().findFirst().ifPresent(log ->
assertTrue(log.getMessage().contains("SimpleConstraint._init")));
// check server log
verify(logger, atLeastOnce()).error(anyString(), contains("F100-ZK-5135.zul"),
contains("SimpleConstraint._init"));
}

// https://stackoverflow.com/a/30703932
private static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
2 changes: 1 addition & 1 deletion zul/src/main/resources/web/js/zul/inp/SimpleConstraint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class SimpleConstraint extends zk.Object {
try {
this._regex = new RegExp(k >= 0 ? cst.substring(j, k) : cst.substring(j), regexFlags || 'g');
} catch (e) {
zk.error((e as Error).message || e as string);
zk.error(e as Error | string);
}

this._cstArr[this._cstArr.length] = 'regex';
Expand Down

0 comments on commit 7bab971

Please sign in to comment.