1

So I really need some helpful hints with an issue I am having with my GWTP application, perhaps one of you have ran into this problem before. So I am using GWTP 1.1 with:

  • com.gwtplatform.mvp.Mvp (Not w/ entry point)
  • com.gwtplatform.dispatch.Dispatch with
  • com.google.gwt.uibinder.UiBinder

The issue I am having is that when ever I have a client sided error (can be almost anywhere in my client side, not sure where the boundary is) I receive a very cryptic message to do with GIN rather than a message that will help me resolve the issue. Seems like something to do with GWTP Proxying, here is the typical message that I get: http://pastebin.com/YgxPbkru the real issue isn't what the error message is presenting to me. The OpenIcidentPresenter extends IncidentPresenter which is a Presenter I have made to manage lifecycles of an Incident (in this case) this extends another presenter that I have made called a RequestPresenter, this is a Presenter that allows the user to Request PresenterWidget classes into it (into any given slot for that presenters lifecycle), this extends another presenter called RichPresenter, which just has things that almost all my Presenters require like page load indication and certain page locking etc, etc. Here are these classes:

OpenIncidentPresenter

public class OpenIncidentPresenter extends IncidentPresenter<OpenIncidentPresenter.MyView,
        OpenIncidentPresenter.MyProxy> implements ViewUiHandlers, HasRequestedWidgets, NewIncidentHandler,
        ChangeSectionHandler, ConfigureHandler {

        public interface MyView extends View, HasUiHandlers<ViewUiHandlers> {
                ... Snip ...
        }

        @ProxyCodeSplit
        @NameToken(NameTokens.open)
        //@UseGatekeeper(LoginGatekeeper.class)
        public interface MyProxy extends ProxyPlace<OpenIncidentPresenter> {
        }

        private static Logger logger = Logger.getLogger(OpenIncidentPresenter.class.getName());

        Process process;

        SectionTuple currentSection = new SectionTuple();

        Map<Integer, SectionTuple> sections = new HashMap<Integer, SectionTuple>();
        List<AccordionSection> sectionWigets = new ArrayList<AccordionSection>();

        List<Activity> cachedActivities = new ArrayList<Activity>();
        List<Authority> cachedAuthorities = new ArrayList<Authority>();
        List<Severity> cachedSeverities = new ArrayList<Severity>();
        List<Location> cachedLocations = new ArrayList<Location>();
        List<Site> cachedSites = new ArrayList<Site>();
        List<Area> cachedAreas = new ArrayList<Area>();

        Severity currentSeverity;
        boolean configured = false;
        boolean changedConsequences = false;

        final ImageResources imageResources;

        RegisteredRequestWidget<ActionBarPresenterWidget> actionBarReg;
        RegisteredRequestWidget<ProgressBarPresenterWidget> progressBarReg;

        @Inject
        public OpenIncidentPresenter(final EventBus eventBus, final MyView view,
                        final MyProxy proxy, final DispatchAsync dispatch,
                        final PlaceManager placeManager, ImageResources imageResources) {
                super(eventBus, view, proxy, dispatch, placeManager);

                this.imageResources = imageResources;

                getView().setUiHandlers(this);

                logger.log(Level.INFO, "Constructed OpenIncidentPresenter");
        }

        @Override
        protected void revealInParent() {
                RevealContentEvent.fire(this, ApplicationPresenter.SLOT_MIDDLE, this);
        }

        ... Snip ...
}

IncidentPresenter

public abstract class IncidentPresenter<T extends View,
                H extends Proxy<?>> extends RequestPresenter<T, H> implements HasIncident {

        Logger logger = Logger.getLogger(IncidentPresenter.class.getName());

        public static final String INCIDENT_COOKIE = "incidentId";

        public interface LoadCallback {
                void onFinished();
        }

        protected Incident incident;
        protected DispatchAsync dispatch;

        private boolean loaded = false;

        public IncidentPresenter(EventBus eventBus, T view, H proxy,
                        DispatchAsync dispatch, PlaceManager placeManager) {
                super(eventBus, view, proxy, placeManager, true);

                this.dispatch = dispatch;
        }

        public abstract void onFailureToLoadIncident(Integer incidentId);
        public abstract void onLoadedIncident(Incident incident);

        @Override
        public void loadIncident(final Integer id) {
                loadIncident(id, null);
        }

        @Override
        public void loadIncident(final Integer id, final LoadCallback callback) {
                .. Snip ..
        }

        /**
         * Process the incident dependencies
         */
        protected void loadDependencies(final Incident incident, final LoadCallback callback) {
                .. Snip ..
        }

        @Override
        public Incident getIncident() {
                return incident;
        }

        @Override
        public void setIncident(Incident incident) {
                this.incident = incident;
                if(hasIncident()) {
                        String incidentCookie = Cookies.getCookie("incidentId");
                        if(incidentCookie == null || !incidentCookie.equals(String.valueOf(
                                        incident.getId()))) {
                                // Set the cookie to the new incident id
                                Cookies.setCookie("incidentId", String.valueOf(incident.getId()));

                                logger.log(Level.INFO, "Set incident " + String.valueOf(incident.getId())
                                        + " to the cookie session");
                        }
                } else {
                        Cookies.removeCookie("incidentId");
                        logger.log(Level.INFO, "Set incident to null incident object, cleared " +
                                        "the cookie session");
                }
        }

        @Override
        public boolean isIncidentLoaded() {
                return hasIncident() && loaded;
        }

        @Override
        public boolean hasIncident() {
                return IncidentUtils.isValid(incident);
        }

        @Override
        public void resetIncident() {
                setIncident(null);
                loaded = false;
        }

        @Override
        public DispatchAsync getDispatch() {
                return dispatch;
        }

        public String getIncidentCookie() {
                return Cookies.getCookie(INCIDENT_COOKIE);
        }
}

RequestPresenter

public abstract class RequestPresenter<T extends View, H extends Proxy<?>>
                extends RichPresenter<T, H> implements HasRequestedWidgets {

        RequestWidgetManager requestManager = new RequestWidgetManager(this);

        public RequestPresenter(EventBus eventBus, T view, H proxy,
                        PlaceManager placeManager) {
                this(eventBus, view, proxy, placeManager, false);
        }

        public RequestPresenter(EventBus eventBus, T view, H proxy,
                        PlaceManager placeManager, boolean leaveConfirmation) {
                super(eventBus, view, proxy, placeManager, leaveConfirmation);
        }

        @Override
        public void prepareFromRequest(PlaceRequest request) {
                prepareFromRequest(request, null);
        }

        /**
         * Alternative to {@link RequestPresenter#prepareFromRequest(PlaceRequest)} that
         * will allow you to register the {@link FinalCallback} in case you have dependency
         * on the request widgets.
         * @param request
         * @param callback
         */
        public void prepareFromRequest(PlaceRequest request, FinalCallback callback) {
                super.prepareFromRequest(request);

                executeAfterRequesting(callback);
                requestWidgets();
        }

        @Override
        protected void onBind() {
                super.onBind();

                registerRequestWidgets();
        }

        @Override
        protected void onUnbind() {
                super.onUnbind();

                unregisterRequestWidgets();
        }

        @Override
        protected void onHide() {
                super.onHide();

                dismissWidgets();
        }

        @Override
        protected void onReveal() {
                super.onReveal();

                requestWidgets();
        }

        private void requestWidgets() {
                requestManager.requestAll();

                onRequestWidgets();
        }

        private void dismissWidgets() {
                requestManager.dismissAll();

                onDismissWidgets();
        }

        public void unregisterRequestWidgets() {
                requestManager.unregisterAllWidgets();
        }

        @Override
        public abstract void registerRequestWidgets();

        public void onRequestWidgets() {
                // Do nothing by default
        }

        public void onDismissWidgets() {
                // Do nothing by default
        }

        protected RequestWidgetManager getRequestManager() {
                return requestManager;
        }

        /**
         * This will execute the callback method when the final request is made on loading.<br>
         * This must be set before super.onReveal or super.prepareFromRequest are called.
         * Or use {@link RequestPresenter#prepareFromRequest(PlaceRequest, FinalCallback)} to
         * set the final callback.
         * @param callback
         */
        public void executeAfterRequesting(FinalCallback callback) {
                requestManager.setFinalCallback(callback);
        }

        public <P extends PresenterWidget<?>> RequestedWidget<P> getRequestedWidget(
                        RegisteredRequestWidget<P> registry) {
                return requestManager.get(registry);
        }

        public <P extends PresenterWidget<?>> RegisteredRequestWidget<P> registerRequestWidget(
                        HasHandlers handler, Class<P> clazz, Object slot, boolean clearSlot) {
                return registerRequestWidget(handler, clazz, slot, clearSlot, null);
        }

        public <P extends PresenterWidget<?>> RegisteredRequestWidget<P> registerRequestWidget(
                        HasHandlers handler, Class<P> clazz, Object slot, boolean clearSlot,
                        RequestWidgetEvent.Callback<P> callback) {
                return requestManager.registerWidget(handler, clazz, slot, clearSlot, callback);
        }
}

RichPresenter

public abstract class RichPresenter<T extends View,
        H extends Proxy<?>> extends Presenter<T, H> {

        protected final PlaceManager placeManager;

        private boolean leaveConfirmation;
        private String defaultLeaveMessage = "Any unsaved work will be lost when " +
                "leaving this page, are you sure you would like to leave?";

        public RichPresenter(EventBus eventBus, T view, H proxy,
                        PlaceManager placeManager) {
                this(eventBus, view, proxy, placeManager, false);
        }

        public RichPresenter(EventBus eventBus, T view, H proxy,
                        PlaceManager placeManager, boolean leaveConfirmation) {
                super(eventBus, view, proxy);

                this.placeManager = placeManager;
                this.leaveConfirmation = leaveConfirmation;
        }

        /**
         * Setup component control handlers for the UI
         */
        protected void setupHandlers(final T view) {
                // Do nothing by default
        }

        @Override
        public void prepareFromRequest(PlaceRequest request) {
                super.prepareFromRequest(request);

                // Start Load Indicator
                LoadingIndicatorEvent.fire(this, true);

                // Attempt to set leave confirmation
                setLeaveConfirmation(leaveConfirmation);
        }

        @Override
        protected void onBind() {
                super.onBind();

                setupHandlers(getView());
        }

        @Override
        protected void onUnbind() {
                super.onUnbind();

                // Remove all the event handlers
                for(HandlerRegistration reg : handlerRegistrations) {
                        reg.removeHandler();
                }
                handlerRegistrations.clear();
        }

        @Override
        protected void onReveal() {
                super.onReveal();

                // Stop Load Indicator
                LoadingIndicatorEvent.fire(this, true);

                // Attempt to set leave confirmation
                setLeaveConfirmation(leaveConfirmation);
        }

        @Override
        protected void onReset() {
                super.onReset();

                // Stop Load Indicator
                LoadingIndicatorEvent.fire(this, false);
        }

        /**
         * Set the page leave confirmation.
         * @param leaveConfirmation
         */
        public void setLeaveConfirmation(boolean leaveConfirmation) {
                this.leaveConfirmation = leaveConfirmation;

                if(leaveConfirmation && !BrowserUtils.isIEBrowser()) {
                        placeManager.setOnLeaveConfirmation(defaultLeaveMessage);
                } else {
                        placeManager.setOnLeaveConfirmation(null);
                }
        }

        public boolean isConfirmOnLeave() {
                return leaveConfirmation;
        }

        public String getDefaultLeaveMessage() {
                return defaultLeaveMessage;
        }

        public void setDefaultLeaveMessage(String message) {
                this.defaultLeaveMessage = message;
        }
}

I feel like this could be a contributing factor here. I have a large chain of presenters that I could be implementing wrong.

This is making it crazy hard for me to identify issues in my client side code. I have to go through my changes, reverting them until I no longer get this message. Which is just ridiculous. If you can see that I am doing something wrong or need more information let me know please! Would be so greatly appreciated.

Cheers! Ben

Ben Dol
  • 427
  • 6
  • 18

0 Answers0