Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    exportClientData callback to trap errors

    Hi,

    I'm using the exportClientData with a DSRequest, but there is no callback argument.
    I can set willHandleErrors on the DSRequest, but how do I trap these then?

    I want to catch those top-level exceptions on the client, e.g. the one when you try exporting an empty grid:

    Code:
    //isc_RPCResponseStart-->[{status:-1,data:"Export failed - passed empty or invalid data set."}]//isc_RPCResponseEnd
    Code:
    top-level exception
    
    java.lang.Exception: send(rpcRequest, rpcResponse) called twice for the same rpcRequest.  Only one RPCResponse can be sent to an RPCRequest.
    	at com.isomorphic.rpc.RPCManager.send(RPCManager.java:520)
    	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:126)
    	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:95)
    	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)


    SmartGWT EE

    #2
    There's no callback because a callback cannot be provided for the success case (which is a file download).

    Error cases go to central RPCManager error handling as with other errors.

    Comment


      #3
      That's strange, then:
      when I do the export in case of empty grid, I go out of the application and get directed to the IDACall URL, which is a page showing the error from previous post.

      I have set an RPCManager.setHandleErrorCallback(), but that doesn't trap it either.

      Comment


        #4
        You seem to be saying that you're seeing a redirect to IDACall, but the default behavior uses a hidden frame (transport:"hiddenFrame") to initiate the download and in that case normal error handling should apply. Did you customize this?

        If you didn't intend to, can you show the complete code that triggers the export?

        Comment


          #5
          Yes, I've got my own IDACall extended class and it's working fine and hasn't been renamed:
          Code:
          web.xml:
           <servlet-name>IDACall</servlet-name>
          ...
              <servlet-mapping>
                  <servlet-name>IDACall</servlet-name>
                  <url-pattern>/app/sc/IDACall/*</url-pattern>
              </servlet-mapping>

          The URL goes from
          Code:
          http://127.0.0.1:8888/App.html?gwt.codesvr=127.0.0.1:9997
          to
          http://127.0.0.1:8888/app/sc/IDACall?isc_rpc=1&isc_v=SC_SNAPSHOT-2010-12-14&isc_tnum=28
          and the last URL shows an HTML page with the stacktrace, so I get kicked out of the app.
          If there is data in the grid, the export is OK, I stay in the app and a download box shows in IE8.


          The export code is my first try, so basically a copy/paste of the EE showcase example. I must admit I can't get the server side export working at this moment, but I don't think it uses the formatters from the grid's fields, so I won't maybe use it then.

          Code:
          SelectItem exportTypeItem = new SelectItem("exportType", "Export Type");  
          exportTypeItem.setWidth("*");  
          exportTypeItem.setDefaultToFirstOption(true);  
          
          LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();  
          valueMap.put("csv", "CSV (Excel)");  
          valueMap.put("xml", "XML");  
          valueMap.put("json", "JSON");  
          valueMap.put("xls", "XLS (Excel97)");
          valueMap.put("ooxml", "XLSX (Excel2007/OOXML)");
          exportTypeItem.setValueMap(valueMap);
          
          final DynamicForm exportForm = new DynamicForm();
          exportForm.setWidth(300);
          exportForm.setItems(exportTypeItem);
          
          MyIButton doExport = new MyIButton("Export", MyImageConstants.ICON_SKIN_ACTION_DOWNLOAD, 16);
          
          HLayout formLayout = new HLayout(15);
          formLayout.setLayoutMargin(20);
          formLayout.setAutoWidth();
          formLayout.addMember(exportForm);
          formLayout.addMember(doExport);
          
          doExport.addClickHandler(new ClickHandler() {
          
          	public void onClick(ClickEvent event) {
          		String exportAs = (String) exportForm.getField("exportType").getValue();  
          		DSRequest dsRequestProperties = new DSRequest();
          		dsRequestProperties.setShowPrompt(false);
          		dsRequestProperties.setWillHandleError(true);		
          
          dsRequestProperties.setExportAs((ExportFormat)EnumUtil.getEnum(ExportFormat.values(), exportAs));  
          		dsRequestProperties.setExportDisplay(ExportDisplay.DOWNLOAD);
          		resultGrid.exportClientData(dsRequestProperties);
          
          	}
          });

          I can add a check to not allow export when the grid is empty (is this really the best way, fetching all records in a big grid??):
          Code:
          resultGrid.getRecords().length == 0
          but at this point I'm not sure if we won't receive any other error (like a weird unformatted value mixed with XML for instance...) which I would like to catch myself somehow.
          And I don't know now, but maybe the users would like to just download an empty csv file. I can imagine someone doing a daily routine by executing a selection, and saving the result. It's better that he has an empty file for that day instead of no file at all.



          And this is the server log of the export:
          Code:
          DEBUG Reflection - invoking method:
          void com.isomorphic.rpc.BuiltinRPC.downloadClientExport(java.util.List, java.lang.String, java.lang.String, java.lang.String, java.util.Map, javax.servlet.http.HttpServletResponse, com.isomorphic.rpc.RPCManager, com.isomorphic.rpc.RPCRequest) throws java.lang.Exception
          
          with arg types: java.util.ArrayList, java.lang.String, java.lang.String, java.lang.String, org.apache.commons.collections.map.LinkedMap, com.isomorphic.servlet.ProxyHttpServletResponse, com.isomorphic.rpc.RPCManager, com.isomorphic.rpc.RPCRequest
          INFO  BuiltinRPC - Export data passed to server:
          [
          ]
          WARN  BuiltinRPC - unable to process data - returning error
          DEBUG RPCManager - Content type for RPC transaction: text/html; charset=UTF-8
          DEBUG ProxyHttpServletResponse - Using charset: UTF-8 (CompressionFilter)
          DEBUG RPCDMI - rpc returned data

          Comment


            #6
            Hmm, I'm seeing the redirect problem also on a successful export. Chrome, IE, FF, they all give me a window closing event when the download pop-up comes up, but that happens underlying. The page in the browser itself stays on the application page.

            Comment


              #7
              An efficient check for empty data would be getData().getLength().

              Not clear on what your most recent post means. Successful exports don't redirect (in fact it's not possible for them to do so).

              As far as other error cases, exportClientData basically doesn't have any that wo uld occur for a deployed application - is there a case you have in mind?

              Comment


                #8
                Repro of both problems:
                * without data set to the grid, an ugly servlet exception is shown in the application page.
                * with data set, the "file download" dialog causes a ClosingEvent on the browser Window. I thought this was IE specific, but it seems to occur in all browsers.

                Code:
                private void test9() {
                	Window.addWindowClosingHandler(new ClosingHandler() {
                		
                		public void onWindowClosing(ClosingEvent event) {
                			GWT.log("Window onWindowClosing triggered");
                			SC.say("Window is closing");
                		}
                	});
                	
                	final ListGrid grid = new ListGrid();
                	ListGridField field1 = new ListGridField("a");
                	ListGridField field2 = new ListGridField("b");
                	grid.setFields(field1, field2);
                	ListGridRecord record1 = new ListGridRecord();
                	record1.setAttribute("a", "this is a");
                	record1.setAttribute("b", "this is b");
                	ListGridRecord record2 = new ListGridRecord();
                	record2.setAttribute("a", "this is something");
                	record2.setAttribute("b", "this is also something");
                	
                	//Don't add data: ugly error!
                	//Add data: when you click the export button
                	//the "Window is closing" will pop-up when the file download box shows.
                	//grid.setData(new ListGridRecord[]{record1, record2});
                	
                	Button export = new Button("Export grid data");
                	export.addClickHandler(new ClickHandler() {
                		
                		public void onClick(ClickEvent event) {
                			DSRequest requestProperties = new DSRequest();
                			requestProperties.setExportAs(ExportFormat.XML);
                			requestProperties.setExportDisplay(ExportDisplay.DOWNLOAD);
                			grid.exportClientData(requestProperties);
                		}
                	});
                	
                	VLayout layout = new VLayout();
                	layout.setMembers(grid, export);
                	layout.draw();
                }
                Last edited by levi; 27 Dec 2010, 00:49.

                Comment


                  #9
                  So, once again, check the dataset length before proceeding with export. This should avoid any error conditions; let us know if you think there is still an untrappable error case.

                  As far as the ClosingEvent, are you saying you're getting a (spurious) closing window event from GWT, even though the window does not close? If so, then you'll need to work around this bug (a core GWT bug, not a SmartGWT bug), probably by setting a flag to ignore the next window close event when triggering an export.

                  Comment


                    #10
                    Ok, I was kind of hoping the problem of not being able to export an empty grid would be fixed instead.

                    Also, there's no getData() on grid, but this one should work also, right?
                    Code:
                    ListGrid.getDataAsRecordList().getLength()

                    * I think the ClosingEvent problem is more of a browser issue, which triggers closing events because of the "Save file as" dialog pop-up being shown. Does it not ring a bell to anyone?
                    My workaround for manual downloads was to show an HTML link where the user can click on and initiate the download himself. I'll see if I can do the same with exportData (save the file on server, then use a link and a DownloadServlet to pass the file to the user).

                    Comment


                      #11
                      Originally posted by levi
                      I think the ClosingEvent problem is more of a browser issue, which triggers closing events because of the "Save file as" dialog pop-up being shown. Does it not ring a bell to anyone?
                      I'm seeing it with export too with Chrome, IE, and Firefox. I suspect the cause is as you wrote. Unfortunately, there isn't anything in the event, itself, that can be used to distinguish it from a valid close event, so we used the work around suggested by Isomorphic for now.

                      Comment

                      Working...
                      X