5182: Improve error reporting in uploader.
authorTom Clegg <tom@curoverse.com>
Tue, 10 Mar 2015 06:58:58 +0000 (02:58 -0400)
committerTom Clegg <tom@curoverse.com>
Tue, 10 Mar 2015 07:00:10 +0000 (03:00 -0400)
Missing CORS headers (and network errors which force the browser to
assume CORS headers are missing) are reported as error==="". In place
of the enigmatic "error:", we show a message hinting at network/CORS
problems and pointing the user to the browser debug console for
further clues.

Mixed-content errors (https://workbench/*.js attempts AJAX request at
http://proxy/*) don't invoke success/fail handlers at all, so we catch
them ahead of time and show an appropriate message.

apps/workbench/app/assets/javascripts/upload_to_collection.js
apps/workbench/test/integration/collection_upload_test.rb

index d4333faaa92bfe093eaa19219e59a37f2b7cf644..58ac3feb8392b1a50e79e2e41b3993ef4f347dd4 100644 (file)
@@ -65,6 +65,7 @@ function UploadToCollection($scope, $filter, $q, $timeout,
     ////////////////////////////////
 
     var keepProxy;
+    var defaultErrorMessage = 'A network error occurred, or there is a CORS configuration problem. Please check your browser debug console for a more specific error message (browser security features prevent us from showing the details here).';
 
     function SliceReader(_slice) {
         var that = this;
@@ -117,7 +118,20 @@ function UploadToCollection($scope, $filter, $q, $timeout,
             // resolve(locator) when the block is accepted by the
             // proxy.
             _deferred = $.Deferred();
-            goSend();
+            if (proxyUriBase().match(/^http:/) &&
+                window.location.origin.match(/^https:/)) {
+                // In this case, requests will fail, and no ajax
+                // success/fail handlers will be called (!), which
+                // will leave our status saying "uploading" and the
+                // user waiting for something to happen. Better to
+                // give up now.
+                _deferred.reject({
+                    textStatus: 'error',
+                    err: 'server setup problem (proxy ' + proxyUriBase() + ' cannot be used from origin ' + window.location.origin + ')'
+                });
+            } else {
+                goSend();
+            }
             return _deferred.promise();
         }
         function stop() {
@@ -401,7 +415,7 @@ function UploadToCollection($scope, $filter, $q, $timeout,
                      ? (' (from ' + reason.xhr.options.url + ')')
                      : '') +
                     ': ' +
-                    (reason.err || ''));
+                    (reason.err || defaultErrorMessage));
             if (reason.xhr && reason.xhr.responseText)
                 that.stateReason += ' -- ' + reason.xhr.responseText;
             _deferred.reject(reason);
index a2405765b0815fba1d631ec8dbe68e74309c656a..3f201b748c014440d45484fef3692696a1b3f7b6 100644 (file)
@@ -67,6 +67,44 @@ class CollectionUploadTest < ActionDispatch::IntegrationTest
     end
   end
 
+  test "Report mixed-content error" do
+    skip 'Test suite does not use TLS'
+    need_selenium "to make file uploads work"
+    begin
+      use_token :admin
+      proxy = KeepService.find(api_fixture('keep_services')['proxy']['uuid'])
+      proxy.update_attributes service_ssl_flag: false
+    end
+    visit page_with_token 'active', sandbox_path
+    find('.nav-tabs a', text: 'Upload').click
+    attach_file 'file_selector', testfile_path('foo.txt')
+    assert_selector 'button:not([disabled])', text: 'Start'
+    click_button 'Start'
+    using_wait_time 5 do
+      assert_text :visible, 'server setup problem'
+      assert_text :visible, 'cannot be used from origin'
+    end
+  end
+
+  test "Report CORS problem or network error" do
+    need_selenium "to make file uploads work"
+    begin
+      use_token :admin
+      proxy = KeepService.find(api_fixture('keep_services')['proxy']['uuid'])
+      # Even if you somehow do port>2^16, surely nx.example.net won't respond
+      proxy.update_attributes service_host: 'nx.example.net', service_port: 99999
+    end
+    visit page_with_token 'active', sandbox_path
+    find('.nav-tabs a', text: 'Upload').click
+    attach_file 'file_selector', testfile_path('foo.txt')
+    assert_selector 'button:not([disabled])', text: 'Start'
+    click_button 'Start'
+    using_wait_time 5 do
+      assert_text :visible, 'CORS'
+      assert_text :visible, 'network error'
+    end
+  end
+
   protected
 
   def aproject_path