Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-2638

simplify exception handling (avoid wrapping RuntimeExceptions)

XMLWordPrintable

    • Icon: New Feature New Feature
    • Resolution: Fixed
    • Icon: Normal Normal
    • 8.0.0
    • 8.0.0
    • Components
    • Security Level: Jimmy
    • None
    • ZK 8.0.1

      currently exceptions thrown by a user are wrapped into UIExceptions sometimes even several times making it difficult to debug errors:

      as an example an exception in a dynamically included page fragment will output the following (hiding the root cause which could be a user thrown exception):
      org.zkoss.zk.ui.UiException: Error writing 'src' on type org.zkoss.zul.Include at file:/.../index.zul, line:25

      the real cause is wrapped multiple times into UIExceptions/ELExceptions making it difficult to use the default <error-page> element to handle specific exception since everyting is a UiException in the end, even user thrown RuntimeExceptions

      Error Details: org.zkoss.zk.ui.UiException: Error writing 'src' on type org.zkoss.zul.Include at [file:/C:/home/.../src/main/webapp/index.zul, line:25]
      --------------------------------------
      Stack Trace: 
      
      org.zkoss.bind.impl.MiscUtil.mergeExceptionInfo(MiscUtil.java:175)
      org.zkoss.bind.impl.BindEvaluatorXImpl.setValue(BindEvaluatorXImpl.java:61)
      org.zkoss.bind.impl.LoadPropertyBindingImpl.load(LoadPropertyBindingImpl.java:88)
      org.zkoss.bind.impl.BinderImpl.doPropertyChange0(BinderImpl.java:394)
      org.zkoss.bind.impl.BinderImpl.doPropertyChange(BinderImpl.java:371)
      ...
      --------------------------------------
      
      Caused by: org.zkoss.zel.ELException: Error writing 'src' on type org.zkoss.zul.Include
      
      org.zkoss.zel.BeanELResolver.setValue(BeanELResolver.java:174)
      org.zkoss.bind.xel.zel.DynamicPropertiedELResolver.setValue(DynamicPropertiedELResolver.java:86)
      org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:81)
      org.zkoss.xel.zel.XelELResolver.setValue(XelELResolver.java:114)
      org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:104)
      ...
      
      --------------------------------------
      
      Caused by: org.zkoss.zk.ui.UiException: you are not allowed here! at [file:/C:/home/.../src/main/webapp/WEB-INF/zul/includes/myRestrictedPage.zul, line:8]
      
      org.zkoss.bind.impl.MiscUtil.mergeExceptionInfo(MiscUtil.java:175)
      org.zkoss.bind.BindComposer.doBeforeComposeChildren(BindComposer.java:161)
      org.zkoss.zk.ui.impl.UiEngineImpl.doBeforeComposeChildren(UiEngineImpl.java:930)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:869)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:826)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:735)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:797)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:757)
      org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:699)
      org.zkoss.zk.ui.impl.UiEngineImpl.createComponents(UiEngineImpl.java:1080)
      org.zkoss.zk.ui.impl.AbstractExecution.createComponents0(AbstractExecution.java:251)
      org.zkoss.zk.ui.impl.AbstractExecution.createComponents(AbstractExecution.java:243)
      org.zkoss.zul.Include.afterCompose(Include.java:478)
      org.zkoss.zul.Include.applyChangesToContent(Include.java:373)
      org.zkoss.zul.Include.fixMode(Include.java:348)
      org.zkoss.zul.Include.setSrc(Include.java:282)
      ...
      
      --------------------------------------
      
      Caused by: org.zkoss.zk.ui.UiException: you are not allowed here!
      
      org.zkoss.bind.impl.AbstractAnnotatedMethodInvoker.invokeMethod(AbstractAnnotatedMethodInvoker.java:95)
      org.zkoss.bind.impl.BinderImpl.init(BinderImpl.java:342)
      org.zkoss.bind.AnnotateBinder.init(AnnotateBinder.java:57)
      org.zkoss.bind.BindComposer.doBeforeComposeChildren(BindComposer.java:159)
      org.zkoss.zk.ui.impl.UiEngineImpl.doBeforeComposeChildren(UiEngineImpl.java:930)
      ...
      
      --------------------------------------
      
      Caused by: my.package.PermissionDeniedException : you are not allowed here!
      
      my.package.MyRestrictedViewModel.init(MyRestrictedViewModel.java:19)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      ...
      

      if the user wants to throw some kind of PermissionDeniedException (extends RuntimeException) and redirect to a specific error page the exception needs to be unwrapped manually, not knowing how many levels are required in advance.

      in the case above there are 5 levels of exceptions making error handling a real challenge.

      the current mechanism implementing the Expectable interface works avoiding the wrapping but requires extending every thrown exception implementing the Expectable interface

      class PermissionDeniedException extends RuntimeException implements Expectable {
      

      A simpler and more approach could be to let the user decide at runtime whether he wants to wrap his Exception into a UIException otherwise a RuntimeException is assumed to be expectable even without the interface and passed through to the exception handler. Like that the developer can use existing Exceptions of other frameworks and handle them in the <error-page> handler without implementing additional interfaces.

            DevChu DevChu
            cor3000 cor3000
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: