[folks] Bug 655008 — Tidy up error handling in eds backend



commit d0e2285d8b82bdd8c314751a6a294c1ac457f208
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Jul 20 22:08:00 2011 +0100

    Bug 655008 â Tidy up error handling in eds backend
    
    Return more specific error codes from Edsf.PersonaStore methods where
    possible, and in all cases make sure we've got a switch statement on the
    incoming error code. Closes: bgo#655008

 NEWS                                     |    1 +
 backends/eds/lib/edsf-persona-store.vala |  251 +++++++++++++++++++++++++-----
 po/POTFILES.in                           |    1 +
 3 files changed, 212 insertions(+), 41 deletions(-)
---
diff --git a/NEWS b/NEWS
index 59b158a..6a67650 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,7 @@ Bugs fixed:
 * Bug 655745 â Implement read/write support for gender property
 * Bug 649296 â Folks backend files shouldn't begin with "lib"
 * Bug 652657 â Allow writing to properties of all personas
+* Bug 655008 â Tidy up error handling in eds backend
 
 API changes:
 * Swf.Persona retains and exposes its libsocialweb Contact
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index a25e1e5..dfd7f56 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -360,18 +360,78 @@ public class Edsf.PersonaStore : Folks.PersonaStore
         }
       catch (GLib.Error e)
         {
-          /* FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=652425 */
-          throw new PersonaStoreError.INVALID_ARGUMENT (
-              "Can't remove contact: %s\n", e.message);
+          if (e.domain == BookClient.error_quark ())
+            {
+              switch ((BookClientError) e.code)
+                {
+                  case BookClientError.CONTACT_NOT_FOUND:
+                    /* Not an error, since we've got nothing to do! */
+                    return;
+                  /* We don't expect to receive any of the error codes below: */
+                  case BookClientError.NO_SUCH_BOOK:
+                  case BookClientError.CONTACT_ID_ALREADY_EXISTS:
+                  case BookClientError.NO_SUCH_SOURCE:
+                  case BookClientError.NO_SPACE:
+                  default:
+                    /* Fall out */
+                    break;
+                }
+            }
+          else if (e.domain == Client.error_quark ())
+            {
+              switch ((ClientError) e.code)
+                {
+                  case ClientError.REPOSITORY_OFFLINE:
+                    throw new PersonaStoreError.STORE_OFFLINE (
+                        /* Translators: the first parameter is an address book
+                         * URI and the second is a persona UID. */
+                        _("Address book â%sâ is offline, so contact â%sâ cannot be removed."),
+                            this.id, persona.uid);
+                  case ClientError.PERMISSION_DENIED:
+                    throw new PersonaStoreError.PERMISSION_DENIED (
+                        /* Translators: the first parameter is an address book
+                         * URI and the second is an error message. */
+                        _("Permission denied to remove contact â%sâ: %s"),
+                        persona.uid, e.message);
+                  case ClientError.NOT_SUPPORTED:
+                    throw new PersonaStoreError.READ_ONLY (
+                        /* Translators: the parameter is an error message. */
+                        _("Removing contacts isn't supported by this persona store: %s"),
+                            e.message);
+                  case ClientError.AUTHENTICATION_REQUIRED:
+                    /* TODO: Support authentication. bgo#653339 */
+                  /* We expect to receive these, but they don't need special
+                   * error codes: */
+                  case ClientError.INVALID_ARG:
+                  case ClientError.BUSY:
+                  case ClientError.DBUS_ERROR:
+                  case ClientError.OTHER_ERROR:
+                    /* Fall through. */
+                  /* We don't expect to receive any of the error codes below: */
+                  case ClientError.COULD_NOT_CANCEL:
+                  case ClientError.AUTHENTICATION_FAILED:
+                  case ClientError.TLS_NOT_AVAILABLE:
+                  case ClientError.OFFLINE_UNAVAILABLE:
+                  case ClientError.UNSUPPORTED_AUTHENTICATION_METHOD:
+                  case ClientError.SEARCH_SIZE_LIMIT_EXCEEDED:
+                  case ClientError.SEARCH_TIME_LIMIT_EXCEEDED:
+                  case ClientError.INVALID_QUERY:
+                  case ClientError.QUERY_REFUSED:
+                  default:
+                    /* Fall out */
+                    break;
+                }
+            }
+
+          /* Fallback error. */
+          throw new PersonaStoreError.REMOVE_FAILED (
+              _("Can't remove contact â%sâ: %s"), persona.uid, e.message);
         }
     }
 
   /**
    * Prepare the PersonaStore for use.
    *
-   * TODO: we should throw different errors depending on what went wrong when
-   * we were setting up the PersonaStore.
-   *
    * See { link Folks.PersonaStore.prepare}.
    *
    * @since 0.5.UNRELEASED
@@ -386,35 +446,87 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               return;
             }
 
-          /* FIXME: we need better error codes */
-
           try
             {
               this._addressbook = new E.BookClient (this._source);
-            }
-          catch (GLib.Error e1)
-            {
-              throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't get BookClient: %s\n", e1.message);
-            }
 
-          this._addressbook.notify["readonly"].connect (
-              this._address_book_notify_read_only_cb);
+              this._addressbook.notify["readonly"].connect (
+                  this._address_book_notify_read_only_cb);
 
-          try
-            {
               yield this._addressbook.open (true, null);
             }
-          catch (GLib.Error e2)
+          catch (GLib.Error e1)
             {
+              if (e1.domain == BookClient.error_quark ())
+                {
+                  switch ((BookClientError) e1.code)
+                    {
+                      /* We don't expect to receive any of the error codes
+                       * below: */
+                      case BookClientError.NO_SUCH_BOOK:
+                      case BookClientError.NO_SUCH_SOURCE:
+                      case BookClientError.CONTACT_NOT_FOUND:
+                      case BookClientError.CONTACT_ID_ALREADY_EXISTS:
+                      case BookClientError.NO_SPACE:
+                      default:
+                        /* Fall out */
+                        break;
+                    }
+                }
+              else if (e1.domain == Client.error_quark ())
+                {
+                  switch ((ClientError) e1.code)
+                    {
+                      case ClientError.REPOSITORY_OFFLINE:
+                        throw new PersonaStoreError.STORE_OFFLINE (
+                            /* Translators: the parameter is an address book
+                             * URI. */
+                            _("Address book â%sâ is offline."), this.id);
+                      case ClientError.PERMISSION_DENIED:
+                        throw new PersonaStoreError.PERMISSION_DENIED (
+                            /* Translators: the first parameter is an address
+                             * book URI and the second is an error message. */
+                            _("Permission denied to open address book â%sâ: %s"),
+                            this.id, e1.message);
+                      case ClientError.AUTHENTICATION_REQUIRED:
+                        /* TODO: Support authentication. bgo#653339 */
+                      /* We expect to receive these, but they don't need special
+                       * error codes: */
+                      case ClientError.NOT_SUPPORTED:
+                      case ClientError.INVALID_ARG:
+                      case ClientError.BUSY:
+                      case ClientError.DBUS_ERROR:
+                      case ClientError.OTHER_ERROR:
+                        /* Fall through. */
+                      /* We don't expect to receive any of the error codes
+                       * below: */
+                      case ClientError.COULD_NOT_CANCEL:
+                      case ClientError.AUTHENTICATION_FAILED:
+                      case ClientError.TLS_NOT_AVAILABLE:
+                      case ClientError.OFFLINE_UNAVAILABLE:
+                      case ClientError.UNSUPPORTED_AUTHENTICATION_METHOD:
+                      case ClientError.SEARCH_SIZE_LIMIT_EXCEEDED:
+                      case ClientError.SEARCH_TIME_LIMIT_EXCEEDED:
+                      case ClientError.INVALID_QUERY:
+                      case ClientError.QUERY_REFUSED:
+                      default:
+                        /* Fall out */
+                        break;
+                    }
+                }
+
+              /* Fallback error */
               throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't open addressbook: %s\n", e2.message);
+                  /* Translators: the first parameter is an address book URI
+                   * and the second is an error message. */
+                  _("Couldn't open address book â%sâ: %s"), this.id, e1.message);
             }
 
           if (this._addressbook.is_opened () == false)
             {
               throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't open addressbook\n");
+                  /* Translators: the parameter is an address book URI. */
+                  _("Couldn't open address book â%sâ."), this.id);
             }
 
           /* Determine which fields the address book supports. This is necessary
@@ -434,10 +546,11 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                       (Contact.field_name (ContactField.CATEGORIES) in fields);
                 }
             }
-          catch (GLib.Error e5)
+          catch (GLib.Error e2)
             {
               throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't get address book capabilities: %s", e5.message);
+                  /* Translators: the parameteter is an error message. */
+                  _("Couldn't get address book capabilities: %s"), e2.message);
             }
 
           bool got_view = false;
@@ -445,31 +558,87 @@ public class Edsf.PersonaStore : Folks.PersonaStore
             {
               got_view = yield this._addressbook.get_view (this._query_str,
                   out this._ebookview);
-            }
-          catch (GLib.Error e3)
-            {
-              throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't get book view: %s\n", e3.message);
-            }
 
-          if (got_view == false)
-            {
-              throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't get book view\n");
-            }
+              if (got_view == false)
+                {
+                  throw new PersonaStoreError.INVALID_ARGUMENT (
+                      /* Translators: the parameter is an address book URI. */
+                      _("Couldn't get view for address book â%sâ."),
+                          this.id);
+                }
 
-          this._ebookview.objects_added.connect (this._contacts_added_cb);
-          this._ebookview.objects_removed.connect (this._contacts_removed_cb);
-          this._ebookview.objects_modified.connect (this._contacts_changed_cb);
+              this._ebookview.objects_added.connect (this._contacts_added_cb);
+              this._ebookview.objects_removed.connect (this._contacts_removed_cb);
+              this._ebookview.objects_modified.connect (this._contacts_changed_cb);
 
-          try
-            {
               this._ebookview.start ();
             }
-          catch (GLib.Error e4)
+          catch (GLib.Error e3)
             {
+              if (e3.domain == BookClient.error_quark ())
+                {
+                  switch ((BookClientError) e3.code)
+                    {
+                      /* We don't expect to receive any of the error codes
+                       * below: */
+                      case BookClientError.NO_SUCH_BOOK:
+                      case BookClientError.NO_SUCH_SOURCE:
+                      case BookClientError.CONTACT_NOT_FOUND:
+                      case BookClientError.CONTACT_ID_ALREADY_EXISTS:
+                      case BookClientError.NO_SPACE:
+                      default:
+                        /* Fall out */
+                        break;
+                    }
+                }
+              else if (e3.domain == Client.error_quark ())
+                {
+                  switch ((ClientError) e3.code)
+                    {
+                      case ClientError.REPOSITORY_OFFLINE:
+                        throw new PersonaStoreError.STORE_OFFLINE (
+                            /* Translators: the parameter is an address book
+                             * URI. */
+                            _("Address book â%sâ is offline."), this.id);
+                      case ClientError.PERMISSION_DENIED:
+                        throw new PersonaStoreError.PERMISSION_DENIED (
+                            /* Translators: the first parameter is an address
+                             * book URI and the second is an error message. */
+                            _("Permission denied to open address book â%sâ: %s"),
+                            this.id, e3.message);
+                      case ClientError.AUTHENTICATION_REQUIRED:
+                        /* TODO: Support authentication. bgo#653339 */
+                      /* We expect to receive these, but they don't need special
+                       * error codes: */
+                      case ClientError.NOT_SUPPORTED:
+                      case ClientError.INVALID_ARG:
+                      case ClientError.BUSY:
+                      case ClientError.DBUS_ERROR:
+                      case ClientError.OTHER_ERROR:
+                      case ClientError.SEARCH_SIZE_LIMIT_EXCEEDED:
+                      case ClientError.SEARCH_TIME_LIMIT_EXCEEDED:
+                      case ClientError.QUERY_REFUSED:
+                        /* Fall through. */
+                      /* We don't expect to receive any of the error codes
+                       * below: */
+                      case ClientError.COULD_NOT_CANCEL:
+                      case ClientError.AUTHENTICATION_FAILED:
+                      case ClientError.TLS_NOT_AVAILABLE:
+                      case ClientError.OFFLINE_UNAVAILABLE:
+                      case ClientError.UNSUPPORTED_AUTHENTICATION_METHOD:
+                      case ClientError.INVALID_QUERY:
+                      default:
+                        /* Fall out */
+                        break;
+                    }
+                }
+
+              /* Fallback error */
               throw new PersonaStoreError.INVALID_ARGUMENT (
-                  "Couldn't start bookview: %s\n", e4.message);
+                  /* Translators: the first parameter is an address book URI
+                   * and the second is an error message. */
+                  _("Couldn't get view for address book â%sâ: %s"),
+                  this.id, e3.message);
             }
 
           this._is_prepared = true;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e5505d5..7c20f68 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,4 +1,5 @@
 [encoding: UTF-8]
+backends/eds/lib/edsf-persona-store.vala
 backends/key-file/kf-backend-factory.vala
 backends/key-file/kf-persona-store.vala
 backends/key-file/kf-persona.vala



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