Search code examples
data-bindingeclipse-rcpjfacee4

e4 databinding converter exception not catch


I have created a custom converter to convert a String back into a Date.

public Object convert(Object fromObject){
   if (fromObject != null && fromObject.toString().trim().length() == 0){
       return null;
   }

   for (DateFormat f : formats){
       try{
            return f.parse(fromObject.toString());
       }catch (ParseException e){
           // Ignore
       }
   }

   throw new RuntimeException(message);
}

Basically, if the string is not parsable a RuntimeException will be thrown.

I have added the converter to the update strategy in the data-dinding and it is being called.

The issue is when the exception is thrown. (For example when i start to type the date in the TextFiled). Instead of appearing the decorator field to indicated an error in the input, the exception is not catch.

The exception appears in the console log (The error in the logs is at the end of the question) as it seems that nobody is catching it.

What i am missing? The exception in the converter should be catch within the updateStrategy and display the error, shouldn't it?

!ENTRY org.eclipse.core.databinding 4 0 2017-08-18 15:16:27.816 !MESSAGE Invalid time Format !STACK 0 java.lang.RuntimeException: Invalid time Format at com.lsespace.earthcare.tds.gui.util.databinding.conversion.StringToJavaTimeTagConverter.convert(StringToJavaTimeTagConverter.java:21) at org.eclipse.core.databinding.UpdateStrategy.convert(UpdateStrategy.java:715) at org.eclipse.core.databinding.UpdateValueStrategy.convert(UpdateValueStrategy.java:1) at org.eclipse.core.databinding.ValueBinding$3.run(ValueBinding.java:175) at org.eclipse.core.databinding.observable.Realm$1.run(Realm.java:149) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.databinding.observable.Realm.safeRun(Realm.java:153) at org.eclipse.core.databinding.observable.Realm.exec(Realm.java:171) at org.eclipse.core.databinding.ValueBinding.doUpdate(ValueBinding.java:158) at org.eclipse.core.databinding.ValueBinding.access$4(ValueBinding.java:147) at org.eclipse.core.databinding.ValueBinding$1.handleValueChange(ValueBinding.java:46) at org.eclipse.core.databinding.observable.value.ValueChangeEvent.dispatch(ValueChangeEvent.java:70) at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:117) at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.fireValueChange(DecoratingObservableValue.java:61) at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.handleValueChange(DecoratingObservableValue.java:103) at org.eclipse.core.databinding.observable.value.DecoratingObservableValue$1.handleValueChange(DecoratingObservableValue.java:76) at org.eclipse.core.databinding.observable.value.ValueChangeEvent.dispatch(ValueChangeEvent.java:70) at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:117) at org.eclipse.core.databinding.observable.value.AbstractObservableValue.fireValueChange(AbstractObservableValue.java:82) at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.notifyIfChanged(SimplePropertyObservableValue.java:126) at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.access$3(SimplePropertyObservableValue.java:118) at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue$1$1.run(SimplePropertyObservableValue.java:70) at org.eclipse.core.databinding.observable.Realm$1.run(Realm.java:149) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.databinding.observable.Realm.safeRun(Realm.java:153) at org.eclipse.core.databinding.observable.Realm.exec(Realm.java:171) at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue$1.handleEvent(SimplePropertyObservableValue.java:66) at org.eclipse.core.databinding.property.NativePropertyListener.fireChange(NativePropertyListener.java:69) at org.eclipse.jface.internal.databinding.swt.WidgetListener.handleEvent(WidgetListener.java:56) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) at org.eclipse.swt.widgets.Text.wmCommandChild(Text.java:3117) at org.eclipse.swt.widgets.Control.WM_COMMAND(Control.java:4939) at org.eclipse.swt.widgets.Control.windowProc(Control.java:4794) at org.eclipse.swt.widgets.Display.windowProc(Display.java:5115) at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method) at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:2446) at org.eclipse.swt.widgets.Text.callWindowProc(Text.java:262) at org.eclipse.swt.widgets.Control.windowProc(Control.java:4889) at org.eclipse.swt.widgets.Text.windowProc(Text.java:2704) at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102) at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2552) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3814) at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) at org.eclipse.jface.window.Window.open(Window.java:794) at com.lsespace.earthcare.tds.gui.jface.actions.EditConfigAction.run(EditConfigAction.java:39) at org.eclipse.jface.action.Action.runWithEvent(Action.java:473) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) at org.eclipse.jface.action.ActionContributionItem.lambda$5(ActionContributionItem.java:436) at org.eclipse.jface.action.ActionContributionItem$$Lambda$57/765702264.handleEvent(Unknown Source) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4228) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3816) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150) at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:161) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610) at org.eclipse.equinox.launcher.Main.run(Main.java:1519) at org.eclipse.equinox.launcher.Main.main(Main.java:1492)


Solution

  • This is the implementation of the UpdateStrategy that I use so exceptions in the converter are treated like validation exceptions.

    /**
     * This implementation of UpdateValueStrategy does not catch the exceptions thrown by the converter,
     * thus letting the normal mechanism of ValueBinding deal with the exception as it will do with a
     * validation exception.
     *
     */
    public class AlternativeUpdateValueStrategy extends UpdateValueStrategy {
    
     public AlternativeUpdateValueStrategy() {
        this(UpdateValueStrategy.POLICY_UPDATE);
     }
    
     public AlternativeUpdateValueStrategy(int updateStrategy) {
        super(updateStrategy);
     }
    
     @Override
     public Object convert(Object value) {
        if (converter != null) {
            return converter.convert(value);
        }
        return value;
     }
    
    }