[gitg] Improve handling of diff errors



commit 973df228eb2d2ba294e6ec02d336625565a31a38
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sun Dec 7 20:42:21 2014 +0100

    Improve handling of diff errors
    
    Before we would handle errors by passing them to finish_error on the
    uri scheme request. However, it is hard/impossible to obtain error
    information on the js side in this way. Now instead we return a
    special json document (if the resulting content type is json) and show
    an appropriate error message.

 libgitg/gitg-diff-view-request-diff.vala    |   20 +----------
 libgitg/gitg-diff-view-request.vala         |   49 ++++++++++++++++++++++++++-
 libgitg/resources/diff-view-html-builder.js |   26 +++++++++++++-
 libgitg/resources/diff-view.css             |   16 +++++++++
 4 files changed, 89 insertions(+), 22 deletions(-)
---
diff --git a/libgitg/gitg-diff-view-request-diff.vala b/libgitg/gitg-diff-view-request-diff.vala
index 167b55f..1cab3f9 100644
--- a/libgitg/gitg-diff-view-request-diff.vala
+++ b/libgitg/gitg-diff-view-request-diff.vala
@@ -354,25 +354,7 @@ namespace Gitg
 
                        builder.end_object();
 
-                       var gen = new Json.Generator();
-                       gen.set_root(builder.get_root());
-
-                       var stream = new MemoryOutputStream(null, realloc, free);
-                       gen.to_stream(stream, cancellable);
-
-                       if (cancellable != null && cancellable.is_cancelled())
-                       {
-                               throw new IOError.CANCELLED("Cancelled");
-                       }
-
-                       stream.close();
-
-                       uint8[] data = stream.steal_data();
-                       d_size = stream.get_data_size();
-
-                       data = data[0:d_size];
-
-                       return new MemoryInputStream.from_data(data, stream.destroy_function);
+                       return json_to_stream(builder, cancellable, out d_size);
                }
 
                public override InputStream? run_async(Cancellable? cancellable) throws GLib.Error
diff --git a/libgitg/gitg-diff-view-request.vala b/libgitg/gitg-diff-view-request.vala
index 00dc027..62fd59f 100644
--- a/libgitg/gitg-diff-view-request.vala
+++ b/libgitg/gitg-diff-view-request.vala
@@ -120,6 +120,29 @@ namespace Gitg
                        return ret;
                }
 
+               protected InputStream json_to_stream(Json.Builder builder, Cancellable? cancellable, out 
int64 size) throws GLib.Error
+               {
+                       var gen = new Json.Generator();
+                       gen.set_root(builder.get_root());
+
+                       var stream = new MemoryOutputStream(null, realloc, free);
+                       gen.to_stream(stream, cancellable);
+
+                       if (cancellable != null && cancellable.is_cancelled())
+                       {
+                               throw new IOError.CANCELLED("Cancelled");
+                       }
+
+                       stream.close();
+
+                       uint8[] data = stream.steal_data();
+                       size = stream.get_data_size();
+
+                       data = data[0:size];
+
+                       return new MemoryInputStream.from_data(data, stream.destroy_function);
+               }
+
                public void run(Cancellable? cancellable)
                {
                        run_impl.begin(cancellable, (obj, res) => {
@@ -131,7 +154,31 @@ namespace Gitg
                                }
                                catch (Error e)
                                {
-                                       d_request.finish_error(e);
+                                       if (d_mimetype != null && d_mimetype == "application/json")
+                                       {
+                                               var builder = new Json.Builder();
+
+                                               builder.begin_object();
+                                               builder.set_member_name("error").add_string_value(e.message);
+                                               builder.end_object();
+
+                                               try
+                                               {
+                                                       int64 size;
+
+                                                       stream = json_to_stream(builder, cancellable, out 
size);
+                                                       d_request.finish(stream, size, "application/json");
+                                               }
+                                               catch (Error jerror)
+                                               {
+                                                       d_request.finish_error(e);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               d_request.finish_error(e);
+                                       }
+
                                        return;
                                }
 
diff --git a/libgitg/resources/diff-view-html-builder.js b/libgitg/resources/diff-view-html-builder.js
index d6a06df..3244a73 100644
--- a/libgitg/resources/diff-view-html-builder.js
+++ b/libgitg/resources/diff-view-html-builder.js
@@ -661,17 +661,39 @@ function diff_files(files, lines, maxlines, data)
        return f;
 }
 
+function handle_error(data, message) {
+       if (!message)
+       {
+               message = 'unknown internal error';
+       }
+
+       var msg = 'Internal error while loading diff: ' + message;
+
+       self.postMessage({url: data.url, diff_html: '<div class="error"><p>' + html_escape(msg) + 
'</p><p>This usually indicates a bug in gitg. Please consider filing a bug report at <a 
href="https://bugzilla.gnome.org/browse.cgi?product=gitg";>https://bugzilla.gnome.org/browse.cgi?product=gitg</a></p></div>'});
+}
+
 self.onmessage = function(event) {
        var data = event.data;
 
        // Make request to get the diff formatted in json
        var r = new XMLHttpRequest();
 
+       r.onerror = function(e) {
+               handle_error(data, e.target.responseText);
+       };
+
        r.onload = function(e) {
                var j = JSON.parse(r.responseText);
-               var html = diff_files(j.diff, j.lines, j.maxlines, data);
 
-               self.postMessage({url: data.url, diff_html: html});
+               if (j.error !== undefined)
+               {
+                               handle_error(data, j.error);
+               }
+               else
+               {
+                       var html = diff_files(j.diff, j.lines, j.maxlines, data);
+                       self.postMessage({url: data.url, diff_html: html});
+               }
        }
 
        r.open("GET", data.url);
diff --git a/libgitg/resources/diff-view.css b/libgitg/resources/diff-view.css
index 1a80e80..4aa34d4 100644
--- a/libgitg/resources/diff-view.css
+++ b/libgitg/resources/diff-view.css
@@ -268,4 +268,20 @@ span.hunk_stats, span.file_path {
   display: none;
 }
 
+#diff_content div.error {
+  padding: 12px;
+  border: 1px solid #aaa;
+  background-color: #ffdddd;
+  margin: 12px;
+  font-family: initial;
+}
+
+#diff_content div.error p:first-child {
+  margin-top: 0;
+}
+
+#diff_content div.error p:last-child {
+  margin-bottom: 0;
+}
+
 /* vi:ts=2:et */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]