[gexiv2/wip/Jehan/no-warnings-only-gerrors] gexiv2: more variants with GError instead of WARNINGs.




commit b4e12608cdbc872e903b87f8395bd92915ac5625
Author: Jehan <jehan girinstud io>
Date:   Mon Nov 30 00:05:00 2020 +0100

    gexiv2: more variants with GError instead of WARNINGs.
    
    This gets rid of all functions which could fail with a LOG_ERROR(),
    which was basically raising a GLib warning. Use GError instead as this
    is much easier to process for using applications.
    
    For API stability, it results in new public functions, while the
    existing ones keep behaving the same yet are now deprecated in favor of
    the new ones.

 gexiv2/gexiv2-metadata-exif.cpp  | 114 +++++++++------
 gexiv2/gexiv2-metadata-gps.cpp   | 196 ++++++++++++++++++++-----
 gexiv2/gexiv2-metadata-iptc.cpp  |  25 ++--
 gexiv2/gexiv2-metadata-private.h |  43 +++---
 gexiv2/gexiv2-metadata-xmp.cpp   | 114 +++++++++++----
 gexiv2/gexiv2-metadata.cpp       | 220 +++++++++++++++++++++-------
 gexiv2/gexiv2-metadata.h         | 306 ++++++++++++++++++++++++++++++++++++++-
 test/gexiv2-regression.c         |  26 ++--
 8 files changed, 841 insertions(+), 203 deletions(-)
---
diff --git a/gexiv2/gexiv2-metadata-exif.cpp b/gexiv2/gexiv2-metadata-exif.cpp
index 34d6d11..257e128 100644
--- a/gexiv2/gexiv2-metadata-exif.cpp
+++ b/gexiv2/gexiv2-metadata-exif.cpp
@@ -190,10 +190,11 @@ gboolean gexiv2_metadata_set_exif_tag_multiple(GExiv2Metadata* self,
     return FALSE;
 }
 
-gchar* gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::ExifData &exif_data = self->priv->image->exifData();
     
@@ -209,7 +210,7 @@ gchar* gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata *self, co
             return g_strdup (os.str ().c_str ());
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
@@ -233,10 +234,11 @@ gboolean gexiv2_metadata_set_exif_tag_string (GExiv2Metadata *self, const gchar*
     return FALSE;
 }
 
-glong gexiv2_metadata_get_exif_tag_long (GExiv2Metadata *self, const gchar* tag) {
+glong gexiv2_metadata_get_exif_tag_long (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), 0);
     g_return_val_if_fail(tag != NULL, 0);
     g_return_val_if_fail(self->priv->image.get() != NULL, 0);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::ExifData& exif_data = self->priv->image->exifData();
     
@@ -248,46 +250,37 @@ glong gexiv2_metadata_get_exif_tag_long (GExiv2Metadata *self, const gchar* tag)
         if (it != exif_data.end())
             return it->toLong ();
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return 0;
 }
 
-gboolean gexiv2_metadata_set_exif_tag_long (GExiv2Metadata *self, const gchar* tag, glong value) {
+gboolean gexiv2_metadata_set_exif_tag_long (GExiv2Metadata *self, const gchar* tag, glong value, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         self->priv->image->exifData()[tag] = static_cast<int32_t>(value);
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
-/**
- * gexiv2_metadata_get_exif_tag_rational:
- * @self: An instance of #GExiv2Metadata
- * @tag: Name of the tag to fetch
- * @nom: (out): Return value for the nominator of the rational value of @tag
- * @den: (out): Return location for the denominator of the rational value of @tag
- *
- * Get an Exif tag that is stored as a fraction
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- */
-gboolean gexiv2_metadata_get_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint* nom,
-    gint* den) {
+gboolean gexiv2_metadata_try_get_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint* nom,
+    gint* den, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(nom != NULL, FALSE);
     g_return_val_if_fail(den != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::ExifData& exif_data = self->priv->image->exifData();
     
@@ -304,28 +297,18 @@ gboolean gexiv2_metadata_get_exif_tag_rational (GExiv2Metadata *self, const gcha
             return TRUE;
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
-/**
- * gexiv2_metadata_set_exif_tag_rational:
- * @self: An instance of #GExiv2Metadata
- * @tag: Name of the tag to fetch
- * @nom: The nominator of the rational value of @tag
- * @den: The denominator of the rational value of @tag
- *
- * Set an Exif tag that is stored as a fraction
- *
- * Returns: %TRUE on success, %FALSE otherwise.
- */
-gboolean gexiv2_metadata_set_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint nom, 
-    gint den) {
+gboolean gexiv2_metadata_try_set_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint nom,
+    gint den, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::Rational r;
@@ -335,12 +318,51 @@ gboolean gexiv2_metadata_set_exif_tag_rational (GExiv2Metadata *self, const gcha
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
+gboolean gexiv2_metadata_get_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint* nom,
+    gint* den) {
+    GError   *error = nullptr;
+    gboolean  success;
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail(tag != NULL, FALSE);
+    g_return_val_if_fail(nom != NULL, FALSE);
+    g_return_val_if_fail(den != NULL, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_get_exif_tag_rational(self, tag, nom, den, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_set_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint nom,
+    gint den) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail(tag != NULL, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_set_exif_tag_rational(self, tag, nom, den, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
 /**
  * gexiv2_metadata_get_exif_tag_rational_as_double:
  * @self: An instance of #GExiv2Metadata
@@ -356,7 +378,7 @@ gboolean gexiv2_metadata_set_exif_tag_rational (GExiv2Metadata *self, const gcha
  */
 gdouble gexiv2_metadata_get_exif_tag_rational_as_double (GExiv2Metadata *self, const gchar* tag, gdouble 
def) {
     gint nom, den;
-    if (!gexiv2_metadata_get_exif_tag_rational(self, tag, &nom, &den))
+    if (!gexiv2_metadata_try_get_exif_tag_rational(self, tag, &nom, &den, nullptr))
         return def;
     
     if (nom == 0.0) {
@@ -366,49 +388,53 @@ gdouble gexiv2_metadata_get_exif_tag_rational_as_double (GExiv2Metadata *self, c
     return (den != 0.0) ? (double) nom / (double) den : def;
 }
 
-const gchar* gexiv2_metadata_get_exif_tag_label (const gchar* tag) {
+const gchar* gexiv2_metadata_get_exif_tag_label (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::ExifKey key(tag);
         return g_intern_string(key.tagLabel().c_str());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_exif_tag_description (const gchar* tag) {
+const gchar* gexiv2_metadata_get_exif_tag_description (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::ExifKey key(tag);
         return g_intern_string(key.tagDesc().c_str());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_exif_tag_type (const gchar* tag) {
+const gchar* gexiv2_metadata_get_exif_tag_type (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::ExifKey key(tag);
         return Exiv2::TypeInfo::typeName(key.defaultTypeId());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-GBytes* gexiv2_metadata_get_exif_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+GBytes* gexiv2_metadata_get_exif_tag_raw (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     Exiv2::ExifData &exif_data = self->priv->image->exifData();
 
@@ -426,7 +452,7 @@ GBytes* gexiv2_metadata_get_exif_tag_raw (GExiv2Metadata *self, const gchar* tag
             }
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string ("GExiv2"), e.code(), e.what());
     }
 
     return NULL;
@@ -463,7 +489,7 @@ GBytes * gexiv2_metadata_get_exif_data (GExiv2Metadata *self,
 
         return g_bytes_new_take (data, blob.size());
     } catch (Exiv2::Error& e) {
-        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
 
     return NULL;
diff --git a/gexiv2/gexiv2-metadata-gps.cpp b/gexiv2/gexiv2-metadata-gps.cpp
index 7d0d18a..819ab84 100644
--- a/gexiv2/gexiv2-metadata-gps.cpp
+++ b/gexiv2/gexiv2-metadata-gps.cpp
@@ -47,16 +47,17 @@ private:
     GPointer(const GPointer &other);
 };
 
-gboolean gexiv2_metadata_get_gps_longitude (GExiv2Metadata *self, gdouble *longitude) {
+gboolean gexiv2_metadata_try_get_gps_longitude (GExiv2Metadata *self, gdouble *longitude, GError **error) {
     g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail (longitude != NULL, FALSE);
     g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     try {
         double min, sec;
         *longitude = 0.0;
 
-        gchar* longitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLongitudeRef", 
nullptr);
+        gchar* longitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLongitudeRef", 
error);
         GPointer longitude_ref_guard(longitude_ref);
 
         if (longitude_ref == NULL || longitude_ref[0] == '\0') {
@@ -79,6 +80,7 @@ gboolean gexiv2_metadata_get_gps_longitude (GExiv2Metadata *self, gdouble *longi
                 *longitude += sec / 3600.0;
             }
         } else {
+            g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, "Missing key 
'Exif.GPSInfo.GPSLongitude'.");
             return FALSE;
         }
 
@@ -88,24 +90,25 @@ gboolean gexiv2_metadata_get_gps_longitude (GExiv2Metadata *self, gdouble *longi
 
         return TRUE;
     } catch (Exiv2::Error &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     } catch (std::invalid_argument &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, e.what());
     }
 
     return FALSE;
 }
 
-gboolean gexiv2_metadata_get_gps_latitude (GExiv2Metadata *self, gdouble *latitude) {
+gboolean gexiv2_metadata_try_get_gps_latitude (GExiv2Metadata *self, gdouble *latitude, GError **error) {
     g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail (latitude != NULL, FALSE);
     g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     try {
         double min, sec;
         *latitude = 0.0;
 
-        gchar* latitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLatitudeRef", 
nullptr);
+        gchar* latitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLatitudeRef", 
error);
         GPointer latitude_ref_guard(latitude_ref);
 
         if (latitude_ref == NULL || latitude_ref[0] == '\0') {
@@ -128,6 +131,7 @@ gboolean gexiv2_metadata_get_gps_latitude (GExiv2Metadata *self, gdouble *latitu
                 *latitude += sec / 3600.0;
             }
        } else {
+            g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, "Missing key 
'Exif.GPSInfo.GPSLatitude'.");
            return FALSE;
        }
 
@@ -137,18 +141,19 @@ gboolean gexiv2_metadata_get_gps_latitude (GExiv2Metadata *self, gdouble *latitu
 
         return TRUE;
     } catch (Exiv2::Error &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     } catch (std::invalid_argument &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, e.what());
     }
 
     return FALSE;
 }
 
-gboolean gexiv2_metadata_get_gps_altitude (GExiv2Metadata *self, gdouble *altitude) {
+gboolean gexiv2_metadata_try_get_gps_altitude (GExiv2Metadata *self, gdouble *altitude, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(altitude != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     try {
         *altitude = 0.0;
@@ -167,6 +172,7 @@ gboolean gexiv2_metadata_get_gps_altitude (GExiv2Metadata *self, gdouble *altitu
         if (it != exif_data.end () && it->count() == 1) {
             *altitude = convert_rational(it->toRational(0));
         } else {
+            g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, "Missing key 
'Exif.GPSInfo.GPSAltitude'.");
             return FALSE;
         }
 
@@ -175,60 +181,151 @@ gboolean gexiv2_metadata_get_gps_altitude (GExiv2Metadata *self, gdouble *altitu
 
         return TRUE;
     } catch (Exiv2::Error &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     } catch (std::invalid_argument &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, e.what());
     }
 
     return FALSE;
 }
 
-gboolean gexiv2_metadata_get_gps_info (GExiv2Metadata *self, gdouble *longitude, gdouble *latitude,
-    gdouble *altitude) {
-    gboolean result = FALSE;
+gboolean gexiv2_metadata_get_gps_longitude (GExiv2Metadata *self, gdouble *longitude) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (longitude != NULL, FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
 
-    if (!gexiv2_metadata_get_gps_longitude (self, longitude)) {
+    success = gexiv2_metadata_try_get_gps_longitude(self, longitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_get_gps_latitude (GExiv2Metadata *self, gdouble *latitude) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (latitude != NULL, FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_get_gps_latitude(self, latitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_get_gps_altitude (GExiv2Metadata *self, gdouble *altitude) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (altitude != NULL, FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_get_gps_altitude(self, altitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_try_get_gps_info (GExiv2Metadata *self, gdouble *longitude, gdouble *latitude,
+    gdouble *altitude, GError **error) {
+    gboolean result = TRUE;
+
+    if (!gexiv2_metadata_try_get_gps_longitude (self, longitude, error)) {
         *longitude = 0.0;
-    } else {
-        result = TRUE;
+        result = FALSE;
     }
 
-    if (!gexiv2_metadata_get_gps_latitude (self, latitude)) {
+    if (result && !gexiv2_metadata_try_get_gps_latitude (self, latitude, error)) {
         *latitude = 0.0;
-    } else {
-        result = TRUE;
+        result = FALSE;
     }
 
-    if (!gexiv2_metadata_get_gps_altitude (self, altitude)) {
+    if (result && !gexiv2_metadata_try_get_gps_altitude (self, altitude, error)) {
         *altitude = 0.0;
-    } else {
-        result = TRUE;
+        result = FALSE;
     }
 
     return result;
 }
 
+gboolean gexiv2_metadata_get_gps_info (GExiv2Metadata *self, gdouble *longitude, gdouble *latitude,
+    gdouble *altitude) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
 
-gboolean gexiv2_metadata_set_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude, 
-    gdouble altitude) {
+    success = gexiv2_metadata_try_get_gps_info(self, longitude, latitude, altitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_try_set_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude, 
+    gdouble altitude, GError **error) {
     g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     try {
-        gexiv2_metadata_delete_gps_info (self);
+        gexiv2_metadata_try_delete_gps_info (self, error);
+
+        if (error && *error)
+            return FALSE;
 
-        return gexiv2_metadata_update_gps_info (self, longitude, latitude, altitude);
+        return gexiv2_metadata_try_update_gps_info (self, longitude, latitude, altitude, error);
     } catch (Exiv2::Error &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
 
     return FALSE;
 }
 
-gboolean gexiv2_metadata_update_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude,
+gboolean gexiv2_metadata_set_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude,
     gdouble altitude) {
+    GError   *error = nullptr;
+    gboolean  success;
+
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_set_gps_info(self, longitude, latitude, altitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+gboolean gexiv2_metadata_try_update_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude,
+    gdouble altitude, GError **error) {
     g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     try {
         Exiv2::ExifData& exif_data = self->priv->image->exifData();
@@ -293,16 +390,34 @@ gboolean gexiv2_metadata_update_gps_info (GExiv2Metadata *self, gdouble longitud
         
         return TRUE;
     } catch (Exiv2::Error &e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
 
     return FALSE;
 }
 
+gboolean gexiv2_metadata_update_gps_info (GExiv2Metadata *self, gdouble longitude, gdouble latitude,
+    gdouble altitude) {
+    GError   *error = nullptr;
+    gboolean  success;
 
-void gexiv2_metadata_delete_gps_info (GExiv2Metadata *self) {
+    g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail (self->priv->image.get() != NULL, FALSE);
+
+    success = gexiv2_metadata_try_update_gps_info(self, longitude, latitude, altitude, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
+void gexiv2_metadata_try_delete_gps_info (GExiv2Metadata *self, GError **error) {
     g_return_if_fail(GEXIV2_IS_METADATA (self));
     g_return_if_fail(self->priv->image.get() != NULL);
+    g_return_if_fail(error == nullptr || *error == nullptr);
     
     try {
         Exiv2::ExifData& exif_data = self->priv->image->exifData();
@@ -316,7 +431,7 @@ void gexiv2_metadata_delete_gps_info (GExiv2Metadata *self) {
                 ++exif_it;
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     /* FIXME: two blocks shall ensure to erase in xmp data, if erasing in exif
@@ -335,7 +450,22 @@ void gexiv2_metadata_delete_gps_info (GExiv2Metadata *self) {
         }
         
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        if (error && *error == nullptr)
+            g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
+    }
+}
+
+void gexiv2_metadata_delete_gps_info (GExiv2Metadata *self) {
+    GError *error = nullptr;
+
+    g_return_if_fail (GEXIV2_IS_METADATA (self));
+    g_return_if_fail (self->priv->image.get() != NULL);
+
+    gexiv2_metadata_try_delete_gps_info(self, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
     }
 }
 
diff --git a/gexiv2/gexiv2-metadata-iptc.cpp b/gexiv2/gexiv2-metadata-iptc.cpp
index 303d61a..d64f7ca 100644
--- a/gexiv2/gexiv2-metadata-iptc.cpp
+++ b/gexiv2/gexiv2-metadata-iptc.cpp
@@ -122,10 +122,11 @@ gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* t
     return NULL;
 }
 
-gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
     
@@ -141,7 +142,7 @@ gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, co
             return g_strdup (os.str ().c_str ());
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return NULL;
@@ -245,49 +246,53 @@ gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gcha
     return FALSE;
 }
 
-const gchar* gexiv2_metadata_get_iptc_tag_label (const gchar* tag) {
+const gchar* gexiv2_metadata_get_iptc_tag_label (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::IptcKey key (tag);
         return Exiv2::IptcDataSets::dataSetTitle (key.tag (), key.record ());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_iptc_tag_description (const gchar* tag) {
+const gchar* gexiv2_metadata_get_iptc_tag_description (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::IptcKey key (tag);
         return Exiv2::IptcDataSets::dataSetDesc (key.tag (), key.record ());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_iptc_tag_type (const gchar* tag) {
+const gchar* gexiv2_metadata_get_iptc_tag_type (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         Exiv2::IptcKey key (tag);
         return Exiv2::TypeInfo::typeName(Exiv2::IptcDataSets::dataSetType(key.tag(), key.record()));
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
     
     return NULL;
 }
 
-GBytes* gexiv2_metadata_get_iptc_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+GBytes* gexiv2_metadata_get_iptc_tag_raw (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
 
@@ -305,7 +310,7 @@ GBytes* gexiv2_metadata_get_iptc_tag_raw (GExiv2Metadata *self, const gchar* tag
             }
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
     }
 
     return NULL;
diff --git a/gexiv2/gexiv2-metadata-private.h b/gexiv2/gexiv2-metadata-private.h
index 7675945..47bc118 100644
--- a/gexiv2/gexiv2-metadata-private.h
+++ b/gexiv2/gexiv2-metadata-private.h
@@ -33,11 +33,6 @@ struct _GExiv2MetadataPrivate
     GExiv2PreviewProperties **preview_properties;
 };
 
-#ifndef __GTK_DOC_IGNORE__
-#define LOG_ERROR(e) \
-    g_warning("%s", e.what());
-#endif
-
 /* private EXIF functions */
 
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_has_exif_tag            (GExiv2Metadata *self, const 
gchar* tag);
@@ -49,14 +44,14 @@ G_GNUC_INTERNAL gboolean gexiv2_metadata_set_exif_tag_multiple(GExiv2Metadata* s
                                                                const gchar* tag,
                                                                const gchar** values,
                                                                GError** error);
-G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata 
*self, const gchar* tag);
-G_GNUC_INTERNAL glong                  gexiv2_metadata_get_exif_tag_long       (GExiv2Metadata *self, const 
gchar* tag);
-G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_exif_tag_long       (GExiv2Metadata *self, const 
gchar* tag, glong value);
+G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata 
*self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL glong                  gexiv2_metadata_get_exif_tag_long       (GExiv2Metadata *self, const 
gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_exif_tag_long       (GExiv2Metadata *self, const 
gchar* tag, glong value, GError **error);
 G_GNUC_INTERNAL gdouble                        gexiv2_metadata_get_exif_tag_rational_as_double 
(GExiv2Metadata *self, const gchar* tag, gdouble def);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_label      (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_description (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_type (const gchar* tag);
-G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_exif_tag_raw        (GExiv2Metadata 
*self, const gchar* tag);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_label      (const gchar* tag, GError **error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_description (const gchar* tag, GError **error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_exif_tag_type (const gchar* tag, GError **error);
+G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_exif_tag_raw        (GExiv2Metadata 
*self, const gchar* tag, GError **error);
 
 /* private XMP functions */
 
@@ -64,17 +59,17 @@ G_GNUC_INTERNAL gboolean            gexiv2_metadata_clear_xmp_tag           
(GExiv2Metadata *self,
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_has_xmp_tag                     (GExiv2Metadata 
*self, const gchar* tag);
 G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_xmp_tag_string      (GExiv2Metadata *self, const 
gchar* tag, GError **error);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_string      (GExiv2Metadata *self, const 
gchar* tag, const gchar* value, GError **error);
-G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, 
const gchar* tag);
-G_GNUC_INTERNAL glong                  gexiv2_metadata_get_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag);
-G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag, glong value);
+G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, 
const gchar* tag, GError **error);
+G_GNUC_INTERNAL glong                  gexiv2_metadata_get_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_long        (GExiv2Metadata *self, const 
gchar* tag, glong value, GError **error);
 G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, 
const gchar* tag, GError **error);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const 
gchar* tag, const gchar** values, GError **error);
 
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_label               (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_description (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_type        (const gchar* tag);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_label               (const gchar* tag, GError 
**error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_description (const gchar* tag, GError **error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_xmp_tag_type        (const gchar* tag, GError **error);
 
-G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_xmp_tag_raw         (GExiv2Metadata 
*self, const gchar* tag);
+G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_xmp_tag_raw         (GExiv2Metadata 
*self, const gchar* tag, GError **error);
 
 /* private IPTC functions */
 
@@ -82,15 +77,15 @@ G_GNUC_INTERNAL gboolean            gexiv2_metadata_clear_iptc_tag          
(GExiv2Metadata *self,
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_has_iptc_tag            (GExiv2Metadata *self, const 
gchar* tag);
 G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_iptc_tag_string     (GExiv2Metadata *self, const 
gchar* tag, GError **error);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_iptc_tag_string     (GExiv2Metadata *self, const 
gchar* tag, const gchar* value, GError **error);
-G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata 
*self, const gchar* tag);
+G_GNUC_INTERNAL gchar*                 gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata 
*self, const gchar* tag, GError **error);
 G_GNUC_INTERNAL gchar**                        gexiv2_metadata_get_iptc_tag_multiple   (GExiv2Metadata 
*self, const gchar* tag, GError **error);
 G_GNUC_INTERNAL gboolean               gexiv2_metadata_set_iptc_tag_multiple   (GExiv2Metadata *self, const 
gchar* tag, const gchar** values, GError **error);
 
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_label      (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_description        (const gchar* tag);
-G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_type       (const gchar* tag);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_label      (const gchar* tag, GError **error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_description        (const gchar* tag, GError 
**error);
+G_GNUC_INTERNAL const gchar*   gexiv2_metadata_get_iptc_tag_type       (const gchar* tag, GError **error);
 
-G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_iptc_tag_raw        (GExiv2Metadata 
*self, const gchar* tag);
+G_GNUC_INTERNAL GBytes*                        gexiv2_metadata_get_iptc_tag_raw        (GExiv2Metadata 
*self, const gchar* tag, GError **error);
 
 G_END_DECLS
 
diff --git a/gexiv2/gexiv2-metadata-xmp.cpp b/gexiv2/gexiv2-metadata-xmp.cpp
index 87795a4..d3ff024 100644
--- a/gexiv2/gexiv2-metadata-xmp.cpp
+++ b/gexiv2/gexiv2-metadata-xmp.cpp
@@ -30,35 +30,71 @@ void gexiv2_metadata_clear_xmp(GExiv2Metadata *self) {
     self->priv->image->xmpData().clear();
 }
 
-gchar *gexiv2_metadata_generate_xmp_packet(GExiv2Metadata *self, 
-    GExiv2XmpFormatFlags xmp_format_flags, guint32 padding) {
+gchar *gexiv2_metadata_try_generate_xmp_packet(GExiv2Metadata *self,
+    GExiv2XmpFormatFlags xmp_format_flags, guint32 padding, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, nullptr);
     
     Exiv2::XmpData &xmp_data = self->priv->image->xmpData();
     try {
         if (Exiv2::XmpParser::encode(self->priv->image->xmpPacket(), xmp_data, xmp_format_flags, padding) == 
0)
           return g_strdup(self->priv->image->xmpPacket().c_str());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-gchar *gexiv2_metadata_get_xmp_packet(GExiv2Metadata *self) {
+gchar *gexiv2_metadata_generate_xmp_packet(GExiv2Metadata *self,
+    GExiv2XmpFormatFlags xmp_format_flags, guint32 padding) {
+    gchar  *value;
+    GError *error = nullptr;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_generate_xmp_packet (self, xmp_format_flags, padding, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
+gchar *gexiv2_metadata_try_get_xmp_packet(GExiv2Metadata *self, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
     
     try {
         return g_strdup(self->priv->image->xmpPacket().c_str());
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
+gchar *gexiv2_metadata_get_xmp_packet(GExiv2Metadata *self) {
+    gchar  *value;
+    GError *error = nullptr;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_xmp_packet (self, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
 gboolean gexiv2_metadata_has_xmp_tag(GExiv2Metadata *self, const gchar* tag) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
@@ -142,16 +178,17 @@ gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* ta
         if (it != xmp_data.end())
             return g_strdup (it->toString ().c_str ());
     } catch (Exiv2::Error& e) {
-        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-gchar* gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
     
@@ -167,16 +204,17 @@ gchar* gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, con
             return g_strdup (os.str ().c_str ());
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar* tag, GExiv2StructureType 
type) {
+gboolean gexiv2_metadata_try_set_xmp_tag_struct (GExiv2Metadata *self, const gchar* tag, GExiv2StructureType 
type, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     Exiv2::XmpTextValue tv("");
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
@@ -200,7 +238,7 @@ gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar*
         break;
       case GEXIV2_STRUCTURE_XA_LANG:
       default:
-        g_warning("Invalid structure type.");
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), 0, "Invalid structure type.");
         return FALSE;
         break;
     }
@@ -209,12 +247,30 @@ gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar*
         xmp_data.add(Exiv2::XmpKey(tag), &tv);
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
+gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar* tag, GExiv2StructureType 
type) {
+    GError   *error   = nullptr;
+    gboolean  success = FALSE;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
+    g_return_val_if_fail(tag != nullptr, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+    success = gexiv2_metadata_try_set_xmp_tag_struct (self, tag, type, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
 gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *self, const gchar* tag, 
     const gchar* value, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
@@ -228,16 +284,17 @@ gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *self, const gchar*
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
-glong gexiv2_metadata_get_xmp_tag_long (GExiv2Metadata *self, const gchar* tag) {
+glong gexiv2_metadata_get_xmp_tag_long (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), 0);
     g_return_val_if_fail(tag != NULL, 0);
     g_return_val_if_fail(self->priv->image.get() != NULL, 0);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
     
@@ -249,23 +306,24 @@ glong gexiv2_metadata_get_xmp_tag_long (GExiv2Metadata *self, const gchar* tag)
         if (it != xmp_data.end())
             return it->toLong ();
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return 0;
 }
 
-gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* tag, glong value) {
+gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* tag, glong value, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         self->priv->image->xmpData()[tag] = value;
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
@@ -297,7 +355,7 @@ gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar*
             return array;
         }
     } catch (Exiv2::Error& e) {
-        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     gchar **array = g_new (gchar*, 1);
@@ -334,52 +392,56 @@ gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar
         
         return TRUE;
     } catch (Exiv2::Error& e) {
-        g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return FALSE;
 }
 
-const gchar* gexiv2_metadata_get_xmp_tag_label (const gchar* tag) {
+const gchar* gexiv2_metadata_get_xmp_tag_label (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         return Exiv2::XmpProperties::propertyTitle(Exiv2::XmpKey(tag));
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_xmp_tag_description (const gchar* tag) {
+const gchar* gexiv2_metadata_get_xmp_tag_description (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         return Exiv2::XmpProperties::propertyDesc(Exiv2::XmpKey(tag));
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-const gchar* gexiv2_metadata_get_xmp_tag_type (const gchar* tag) {
+const gchar* gexiv2_metadata_get_xmp_tag_type (const gchar* tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
     
     try {
         return Exiv2::TypeInfo::typeName(Exiv2::XmpProperties::propertyType(Exiv2::XmpKey(tag)));
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
     
     return NULL;
 }
 
-GBytes* gexiv2_metadata_get_xmp_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+GBytes* gexiv2_metadata_get_xmp_tag_raw (GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+    g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
 
     Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
 
@@ -397,7 +459,7 @@ GBytes* gexiv2_metadata_get_xmp_tag_raw (GExiv2Metadata *self, const gchar* tag)
             }
         }
     } catch (Exiv2::Error& e) {
-        LOG_ERROR(e);
+        g_set_error_literal(error, g_quark_from_string("GExiv2"), e.code(), e.what());
     }
 
     return NULL;
diff --git a/gexiv2/gexiv2-metadata.cpp b/gexiv2/gexiv2-metadata.cpp
index 9338247..baec70f 100644
--- a/gexiv2/gexiv2-metadata.cpp
+++ b/gexiv2/gexiv2-metadata.cpp
@@ -705,7 +705,7 @@ GExiv2Orientation gexiv2_metadata_get_orientation (GExiv2Metadata *self) {
         // Because some camera set a wrong standard exif orientation tag,
         // We need to check makernote tags first!
         if (gexiv2_metadata_has_exif_tag(self, "Exif.MinoltaCs7D.Rotation")) {
-            long orientation = gexiv2_metadata_get_exif_tag_long(self, "Exif.MinoltaCs7D.Rotation");
+            long orientation = gexiv2_metadata_get_exif_tag_long(self, "Exif.MinoltaCs7D.Rotation", nullptr);
             switch (orientation) {
                 case 76:
                     return GEXIV2_ORIENTATION_ROT_90;
@@ -719,7 +719,7 @@ GExiv2Orientation gexiv2_metadata_get_orientation (GExiv2Metadata *self) {
         }
 
         if (gexiv2_metadata_has_exif_tag(self, "Exif.MinoltaCs5D.Rotation")) {
-            long orientation = gexiv2_metadata_get_exif_tag_long(self, "Exif.MinoltaCs5D.Rotation");
+            long orientation = gexiv2_metadata_get_exif_tag_long(self, "Exif.MinoltaCs5D.Rotation", nullptr);
             switch (orientation) {
                 case 76:
                     return GEXIV2_ORIENTATION_ROT_90;
@@ -734,7 +734,7 @@ GExiv2Orientation gexiv2_metadata_get_orientation (GExiv2Metadata *self) {
         }
         
         GExiv2Orientation orientation = (GExiv2Orientation) gexiv2_metadata_get_exif_tag_long(self,
-            "Exif.Image.Orientation");
+            "Exif.Image.Orientation", nullptr);
         if (orientation >= GEXIV2_ORIENTATION_MIN && orientation <= GEXIV2_ORIENTATION_MAX)
             return orientation;
     }
@@ -742,7 +742,7 @@ GExiv2Orientation gexiv2_metadata_get_orientation (GExiv2Metadata *self) {
     GExiv2Orientation orientation = GEXIV2_ORIENTATION_UNSPECIFIED;
     if (gexiv2_metadata_has_xmp_tag(self, "Xmp.tiff.ImageWidth")) {
         orientation = (GExiv2Orientation) gexiv2_metadata_get_xmp_tag_long(self,
-            "Xmp.tiff.ImageWidth");
+            "Xmp.tiff.ImageWidth", nullptr);
     }
     
     return (orientation < GEXIV2_ORIENTATION_MIN || orientation > GEXIV2_ORIENTATION_MAX)
@@ -806,18 +806,18 @@ gint gexiv2_metadata_get_metadata_pixel_width (GExiv2Metadata *self) {
     
     if (gexiv2_metadata_has_exif(self)) {
         if (gexiv2_metadata_has_exif_tag(self, "Exif.Photo.PixelXDimension"))
-            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Photo.PixelXDimension");
+            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Photo.PixelXDimension", nullptr);
         
         if (gexiv2_metadata_has_exif_tag(self, "Exif.Image.ImageWidth"))
-            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Image.ImageWidth");
+            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Image.ImageWidth", nullptr);
     }
     
     if (gexiv2_metadata_has_xmp(self)) {
         if (gexiv2_metadata_has_xmp_tag(self, "Xmp.tiff.ImageWidth"))
-            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.tiff.ImageWidth");
+            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.tiff.ImageWidth", nullptr);
         
         if (gexiv2_metadata_has_xmp_tag(self, "Xmp.exif.PixelXDimension"))
-            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.exif.PixelXDimension");
+            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.exif.PixelXDimension", nullptr);
     }
     
     return -1;
@@ -829,18 +829,18 @@ gint gexiv2_metadata_get_metadata_pixel_height (GExiv2Metadata *self) {
     
     if (gexiv2_metadata_has_exif(self)) {
         if (gexiv2_metadata_has_exif_tag(self, "Exif.Photo.PixelYDimension"))
-            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Photo.PixelYDimension");
+            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Photo.PixelYDimension", nullptr);
         
         if (gexiv2_metadata_has_exif_tag(self, "Exif.Image.ImageLength"))
-            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Image.ImageLength");
+            return gexiv2_metadata_get_exif_tag_long(self, "Exif.Image.ImageLength", nullptr);
     }
     
     if (gexiv2_metadata_has_xmp(self)) {
         if (gexiv2_metadata_has_xmp_tag(self, "Xmp.tiff.ImageHeight"))
-            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.tiff.ImageHeight");
+            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.tiff.ImageHeight", nullptr);
             
         if (gexiv2_metadata_has_xmp_tag(self, "Xmp.exif.PixelYDimension"))
-            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.exif.PixelYDimension");
+            return gexiv2_metadata_get_xmp_tag_long(self, "Xmp.exif.PixelYDimension", nullptr);
     }
     
     return -1;
@@ -880,37 +880,37 @@ gchar* gexiv2_metadata_get_comment (GExiv2Metadata *self) {
     if (str != NULL && *str != '\0')
         return g_strdup(str);
     
-    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Image.ImageDescription");
+    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Image.ImageDescription", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
         g_free (str);
     
-    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Photo.UserComment");
+    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Photo.UserComment", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
         g_free (str);
     
-    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Image.XPComment");
+    str = gexiv2_metadata_get_exif_tag_interpreted_string (self, "Exif.Image.XPComment", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
         g_free (str);
     
-    str = gexiv2_metadata_get_iptc_tag_interpreted_string (self, "Iptc.Application2.Caption");
+    str = gexiv2_metadata_get_iptc_tag_interpreted_string (self, "Iptc.Application2.Caption", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
         g_free (str);
     
-    str = gexiv2_metadata_get_xmp_tag_interpreted_string (self, "Xmp.dc.description");
+    str = gexiv2_metadata_get_xmp_tag_interpreted_string (self, "Xmp.dc.description", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
         g_free (str);
     
-    str = gexiv2_metadata_get_xmp_tag_interpreted_string (self, "Xmp.acdsee.notes");
+    str = gexiv2_metadata_get_xmp_tag_interpreted_string (self, "Xmp.acdsee.notes", NULL);
     if (str != NULL && *str != '\0')
         return str;
     else
@@ -1034,23 +1034,41 @@ gboolean gexiv2_metadata_set_tag_string (GExiv2Metadata *self, const gchar* tag,
     return success;
 }
 
-gchar* gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_try_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_interpreted_string (self, tag);
+        return gexiv2_metadata_get_xmp_tag_interpreted_string (self, tag, error);
         
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_interpreted_string (self, tag);
+        return gexiv2_metadata_get_exif_tag_interpreted_string (self, tag, error);
         
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_interpreted_string (self, tag);
+        return gexiv2_metadata_get_iptc_tag_interpreted_string (self, tag, error);
     
     return NULL;
 }
 
+gchar* gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
+    gchar  *value;
+    GError *error = nullptr;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+    g_return_val_if_fail(tag != nullptr, nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_tag_interpreted_string(self, tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
 gchar** gexiv2_metadata_try_get_tag_multiple(GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), nullptr);
     g_return_val_if_fail(tag != nullptr, nullptr);
@@ -1123,36 +1141,72 @@ gboolean gexiv2_metadata_set_tag_multiple(GExiv2Metadata *self, const gchar* tag
     return success;
 }
 
-glong gexiv2_metadata_get_tag_long(GExiv2Metadata *self, const gchar* tag) {
+glong gexiv2_metadata_try_get_tag_long(GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), 0);
     g_return_val_if_fail(tag != NULL, 0);
     g_return_val_if_fail(self->priv->image.get() != NULL, 0);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_long(self, tag);
+        return gexiv2_metadata_get_xmp_tag_long(self, tag, error);
     
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_long(self, tag);
+        return gexiv2_metadata_get_exif_tag_long(self, tag, error);
     
     return 0;
 }
 
-gboolean gexiv2_metadata_set_tag_long(GExiv2Metadata *self, const gchar* tag, glong value) {
+glong gexiv2_metadata_get_tag_long(GExiv2Metadata *self, const gchar* tag) {
+    GError *error   = nullptr;
+    glong   value;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
+    g_return_val_if_fail(tag != nullptr, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+    value = gexiv2_metadata_try_get_tag_long(self, tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
+gboolean gexiv2_metadata_try_set_tag_long(GExiv2Metadata *self, const gchar* tag, glong value, GError 
**error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
     g_return_val_if_fail(tag != NULL, FALSE);
     g_return_val_if_fail(self->priv->image.get() != NULL, 0);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_set_xmp_tag_long(self, tag, value);
+        return gexiv2_metadata_set_xmp_tag_long(self, tag, value, error);
     
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_set_exif_tag_long(self, tag, value);
+        return gexiv2_metadata_set_exif_tag_long(self, tag, value, error);
     
     return FALSE;
 }
 
+gboolean gexiv2_metadata_set_tag_long(GExiv2Metadata *self, const gchar* tag, glong value) {
+    GError   *error   = nullptr;
+    gboolean  success = FALSE;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
+    g_return_val_if_fail(tag != nullptr, FALSE);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+    success = gexiv2_metadata_try_set_tag_long(self, tag, value, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return success;
+}
+
 gboolean gexiv2_metadata_get_exposure_time (GExiv2Metadata *self, gint *nom, gint *den) {
-    return gexiv2_metadata_get_exif_tag_rational (self, "Exif.Photo.ExposureTime", nom, den);
+    return gexiv2_metadata_try_get_exif_tag_rational (self, "Exif.Photo.ExposureTime", nom, den, nullptr);
 }
 
 gdouble gexiv2_metadata_get_fnumber (GExiv2Metadata *self) {
@@ -1175,7 +1229,7 @@ gdouble gexiv2_metadata_get_focal_length (GExiv2Metadata *self) {
 }
 
 gint gexiv2_metadata_get_iso_speed (GExiv2Metadata *self) {
-    return (gint) gexiv2_metadata_get_exif_tag_long (self, "Exif.Photo.ISOSpeedRatings");
+    return (gint) gexiv2_metadata_get_exif_tag_long (self, "Exif.Photo.ISOSpeedRatings", NULL);
 }
 
 GExiv2PreviewProperties** gexiv2_metadata_get_preview_properties (GExiv2Metadata *self) {
@@ -1249,66 +1303,132 @@ void gexiv2_metadata_erase_exif_thumbnail (GExiv2Metadata *self) {
     thumb.erase();
 }
 
-const gchar* gexiv2_metadata_get_tag_label (const gchar *tag) {
-    g_return_val_if_fail(tag != NULL, NULL);
+const gchar* gexiv2_metadata_try_get_tag_label (const gchar *tag, GError **error) {
+    g_return_val_if_fail(tag != nullptr, nullptr);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_label(tag);
+        return gexiv2_metadata_get_xmp_tag_label(tag, error);
     
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_label(tag);
+        return gexiv2_metadata_get_exif_tag_label(tag, error);
     
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_label(tag);
+        return gexiv2_metadata_get_iptc_tag_label(tag, error);
     
-    return NULL;
+    return nullptr;
 }
 
-const gchar* gexiv2_metadata_get_tag_description (const gchar *tag) {
-    g_return_val_if_fail(tag != NULL, NULL);
+const gchar* gexiv2_metadata_get_tag_label (const gchar *tag) {
+    const gchar *value;
+    GError      *error = nullptr;
+
+    g_return_val_if_fail(tag != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_tag_label(tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
+const gchar* gexiv2_metadata_try_get_tag_description (const gchar *tag, GError **error) {
+    g_return_val_if_fail(tag != nullptr, nullptr);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_description(tag);
+        return gexiv2_metadata_get_xmp_tag_description(tag, error);
     
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_description(tag);
+        return gexiv2_metadata_get_exif_tag_description(tag, error);
     
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_description(tag);
+        return gexiv2_metadata_get_iptc_tag_description(tag, error);
     
-    return NULL;
+    return nullptr;
 }
 
-const gchar* gexiv2_metadata_get_tag_type (const gchar *tag) {
+const gchar* gexiv2_metadata_get_tag_description (const gchar *tag) {
+    const gchar *value;
+    GError      *error = nullptr;
+
+    g_return_val_if_fail(tag != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_tag_description(tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
+const gchar* gexiv2_metadata_try_get_tag_type (const gchar *tag, GError **error) {
     g_return_val_if_fail(tag != NULL, NULL);
     
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_type(tag);
+        return gexiv2_metadata_get_xmp_tag_type(tag, error);
     
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_type(tag);
+        return gexiv2_metadata_get_exif_tag_type(tag, error);
     
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_type(tag);
+        return gexiv2_metadata_get_iptc_tag_type(tag, error);
     
     return NULL;
 }
 
-GBytes* gexiv2_metadata_get_tag_raw(GExiv2Metadata *self, const gchar* tag) {
+const gchar* gexiv2_metadata_get_tag_type (const gchar *tag) {
+    const gchar *value;
+    GError      *error = nullptr;
+
+    g_return_val_if_fail(tag != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_tag_type(tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
+GBytes* gexiv2_metadata_try_get_tag_raw(GExiv2Metadata *self, const gchar* tag, GError **error) {
     g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
     g_return_val_if_fail(tag != NULL, NULL);
     g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
 
     if (gexiv2_metadata_is_xmp_tag(tag))
-        return gexiv2_metadata_get_xmp_tag_raw(self, tag);
+        return gexiv2_metadata_get_xmp_tag_raw(self, tag, error);
 
     if (gexiv2_metadata_is_exif_tag(tag))
-        return gexiv2_metadata_get_exif_tag_raw(self, tag);
+        return gexiv2_metadata_get_exif_tag_raw(self, tag, error);
 
     if (gexiv2_metadata_is_iptc_tag(tag))
-        return gexiv2_metadata_get_iptc_tag_raw(self, tag);
+        return gexiv2_metadata_get_iptc_tag_raw(self, tag, error);
 
     return NULL;
 }
 
+GBytes* gexiv2_metadata_get_tag_raw(GExiv2Metadata *self, const gchar* tag) {
+    GBytes *value;
+    GError *error = nullptr;
+
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+    g_return_val_if_fail(tag != nullptr, nullptr);
+    g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+    value = gexiv2_metadata_try_get_tag_raw(self, tag, &error);
+
+    if (error) {
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+
+    return value;
+}
+
 G_END_DECLS
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index 9b26f4c..fe9bfe4 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -393,6 +393,17 @@ gboolean           gexiv2_metadata_is_iptc_tag                             (const gchar* 
tag);
  */
 gboolean               gexiv2_metadata_is_xmp_tag                              (const gchar* tag);
 
+/**
+ * gexiv2_metadata_try_get_tag_label:
+ * @tag: An Exiv2 tag
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer none) (allow-none): The tag's label
+ */
+const gchar*   gexiv2_metadata_try_get_tag_label               (const gchar *tag, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_label:
  * @tag: An Exiv2 tag
@@ -400,9 +411,23 @@ gboolean           gexiv2_metadata_is_xmp_tag                              (const gchar* 
tag);
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: (transfer none) (allow-none): The tag's label
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_label() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_label)
 const gchar*   gexiv2_metadata_get_tag_label           (const gchar *tag);
 
+/**
+ * gexiv2_metadata_try_get_tag_description:
+ * @tag: An Exiv2 tag
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer none) (allow-none): The tag's description
+ */
+const gchar*   gexiv2_metadata_try_get_tag_description (const gchar *tag, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_description:
  * @tag: An Exiv2 tag
@@ -410,9 +435,26 @@ const gchar*       gexiv2_metadata_get_tag_label           (const gchar *tag);
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: (transfer none) (allow-none): The tag's description
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_description() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_description)
 const gchar*   gexiv2_metadata_get_tag_description     (const gchar *tag);
 
+/**
+ * gexiv2_metadata_try_get_tag_type:
+ * @tag: An Exiv2 tag
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * The names of the various Exiv2 tag types can be found at Exiv2::TypeId,
+ * <ulink url="http://exiv2.org/doc/namespaceExiv2.html#5153319711f35fe81cbc13f4b852450c";></ulink>
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer none) (allow-none): The tag's type name.
+ */
+const gchar*   gexiv2_metadata_try_get_tag_type        (const gchar *tag, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_type:
  * @tag: An Exiv2 tag
@@ -423,7 +465,10 @@ const gchar*       gexiv2_metadata_get_tag_description     (const gchar *tag);
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: (transfer none) (allow-none): The tag's type name.
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_type() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_type)
 const gchar*   gexiv2_metadata_get_tag_type    (const gchar *tag);
 
 /**
@@ -556,7 +601,20 @@ G_DEPRECATED_FOR(gexiv2_metadata_try_set_tag_string)
 gboolean               gexiv2_metadata_set_tag_string          (GExiv2Metadata *self, const gchar* tag, 
const gchar* value);
 
 /**
- * gexiv2_metadata_set_tag_struct:
+ * gexiv2_metadata_try_set_xmp_tag_struct:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @type: The GExiv2StructureType specifying the type of structure
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: TRUE on success
+ */
+gboolean gexiv2_metadata_try_set_xmp_tag_struct (GExiv2Metadata *self, const gchar* tag, GExiv2StructureType 
type, GError **error);
+
+/**
+ * gexiv2_metadata_set_xmp_tag_struct:
  * @self: An instance of #GExiv2Metadata
  * @tag: Exiv2 tag name
  * @type: The GExiv2StructureType specifying the type of structure
@@ -564,9 +622,27 @@ gboolean           gexiv2_metadata_set_tag_string          (GExiv2Metadata *self, const 
gchar* ta
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: TRUE on success
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_xmp_tag_struct() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_xmp_tag_struct)
 gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar* tag, GExiv2StructureType 
type);
 
+/**
+ * gexiv2_metadata_try_get_tag_interpreted_string:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * An interpreted string is one fit for user display.  It may display units or use formatting
+ * appropriate to the type of data the tag holds.
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer full) (allow-none): The tag's interpreted value as a string
+ */
+gchar*                 gexiv2_metadata_try_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* 
tag, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_interpreted_string:
  * @self: An instance of #GExiv2Metadata
@@ -578,9 +654,24 @@ gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar*
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: (transfer full) (allow-none): The tag's interpreted value as a string
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_interpreted_string() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_interpreted_string)
 gchar*                 gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
 
+/**
+ * gexiv2_metadata_try_get_tag_long:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: The tag's value as a glong
+ */
+glong                  gexiv2_metadata_try_get_tag_long        (GExiv2Metadata *self, const gchar* tag, 
GError **error);
+
 /**
  * gexiv2_metadata_get_tag_long:
  * @self: An instance of #GExiv2Metadata
@@ -589,9 +680,25 @@ gchar*                     gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata 
*self, const
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: The tag's value as a glong
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_long() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_long)
 glong                  gexiv2_metadata_get_tag_long            (GExiv2Metadata *self, const gchar* tag);
 
+/**
+ * gexiv2_metadata_try_set_tag_long:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @value: The value to set or replace the existing value
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: TRUE on success
+ */
+gboolean               gexiv2_metadata_try_set_tag_long        (GExiv2Metadata *self, const gchar* tag, 
glong value, GError **error);
+
 /**
  * gexiv2_metadata_set_tag_long:
  * @self: An instance of #GExiv2Metadata
@@ -601,10 +708,12 @@ glong                     gexiv2_metadata_get_tag_long            (GExiv2Metadata 
*self, const gchar* tag);
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: TRUE on success
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_tag_long() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_tag_long)
 gboolean               gexiv2_metadata_set_tag_long            (GExiv2Metadata *self, const gchar* tag, 
glong value);
 
-
 /**
  * gexiv2_metadata_try_get_tag_multiple:
  * @self: An instance of #GExiv2Metadata
@@ -668,11 +777,23 @@ gchar**                   gexiv2_metadata_get_tag_multiple        (GExiv2Metadata 
*self, const gchar* t
  *
  * Returns: Boolean success value
  *
- * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_tag_multiple:() instead.
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_tag_multiple() instead.
  */
 G_DEPRECATED_FOR(gexiv2_metadata_try_set_tag_multiple)
 gboolean               gexiv2_metadata_set_tag_multiple        (GExiv2Metadata *self, const gchar* tag, 
const gchar** values);
 
+/**
+ * gexiv2_metadata_try_get_tag_raw:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
+ *
+ * Returns: (transfer full) (allow-none): The tag's raw value as a byte array
+ */
+GBytes*                        gexiv2_metadata_try_get_tag_raw         (GExiv2Metadata *self, const gchar* 
tag, GError **error);
+
 /**
  * gexiv2_metadata_get_tag_raw:
  * @self: An instance of #GExiv2Metadata
@@ -681,7 +802,10 @@ gboolean           gexiv2_metadata_set_tag_multiple        (GExiv2Metadata *self, const 
gchar* t
  * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html";></ulink>
  *
  * Returns: (transfer full) (allow-none): The tag's raw value as a byte array
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_raw() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_raw)
 GBytes*                        gexiv2_metadata_get_tag_raw                     (GExiv2Metadata *self, const 
gchar* tag);
 
 /*
@@ -715,6 +839,36 @@ void                       gexiv2_metadata_clear_exif                      
(GExiv2Metadata *self);
  */
 gchar**                        gexiv2_metadata_get_exif_tags           (GExiv2Metadata *self);
 
+/**
+ * gexiv2_metadata_try_get_exif_tag_rational:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: (in): The tag you want the rational value for
+ * @nom: (out): The numerator
+ * @den: (out): The denominator
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Fetch EXIF @tag represented by a fraction. @nom will contain the numerator,
+ * @den the denominator of the fraction on successful return.
+ *
+ * Returns: (skip): Boolean success value
+ */
+gboolean               gexiv2_metadata_try_get_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, 
gint* nom, gint* den, GError **error);
+
+/**
+ * gexiv2_metadata_try_set_exif_tag_rational:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: (in): The Exiv2 tag
+ * @nom: Rational numerator
+ * @den: Rational denominator
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Set EXIF @tag represented by a fraction, with @nom being the numerator,
+ * @den the denominator of the fraction.
+ *
+ * Returns: (skip): Boolean success value
+ */
+gboolean               gexiv2_metadata_try_set_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, 
gint nom, gint den, GError **error);
+
 /**
  * gexiv2_metadata_get_exif_tag_rational:
  * @self: An instance of #GExiv2Metadata
@@ -726,7 +880,10 @@ gchar**                    gexiv2_metadata_get_exif_tags           (GExiv2Metadata 
*self);
  * @den the denominator of the fraction on successful return.
  *
  * Returns: (skip): Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_exif_tag_rational() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_exif_tag_rational)
 gboolean               gexiv2_metadata_get_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint* 
nom, gint* den);
 
 /**
@@ -740,7 +897,10 @@ gboolean           gexiv2_metadata_get_exif_tag_rational (GExiv2Metadata *self, const gch
  * @den the denominator of the fraction.
  *
  * Returns: (skip): Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_exif_tag_rational() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_exif_tag_rational)
 gboolean               gexiv2_metadata_set_exif_tag_rational (GExiv2Metadata *self, const gchar* tag, gint 
nom, gint den);
 
 /**
@@ -815,6 +975,19 @@ gboolean           gexiv2_metadata_has_xmp                         (GExiv2Metadata 
*self);
  */
 void                   gexiv2_metadata_clear_xmp                       (GExiv2Metadata *self);
 
+/**
+ * gexiv2_metadata_try_generate_xmp_packet:
+ * @self: An instance of #GExiv2Metadata
+ * @xmp_format_flags: One of #GExiv2XmpFormatFlags
+ * @padding: The padding (FIXME: Add documentation)
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Encode the XMP packet as a %NULL-terminated string.
+ *
+ * Returns: (transfer full) (allow-none): Encode the XMP packet and return as a %NULL-terminated string.
+ */
+gchar*         gexiv2_metadata_try_generate_xmp_packet (GExiv2Metadata *self, GExiv2XmpFormatFlags 
xmp_format_flags, guint32 padding, GError **error);
+
 /**
  * gexiv2_metadata_generate_xmp_packet:
  * @self: An instance of #GExiv2Metadata
@@ -824,15 +997,30 @@ void                      gexiv2_metadata_clear_xmp                       
(GExiv2Metadata *self);
  * Encode the XMP packet as a %NULL-terminated string.
  *
  * Returns: (transfer full) (allow-none): Encode the XMP packet and return as a %NULL-terminated string.
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_generate_xmp_packet() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_generate_xmp_packet)
 gchar*         gexiv2_metadata_generate_xmp_packet     (GExiv2Metadata *self, GExiv2XmpFormatFlags 
xmp_format_flags, guint32 padding);
 
+/**
+ * gexiv2_metadata_try_get_xmp_packet:
+ * @self: An instance of #GExiv2Metadata
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Returns: (transfer full) (allow-none): The currently-encoded XMP packet (see 
gexiv2_metadata_generate_xmp_packet).
+ */
+gchar*                 gexiv2_metadata_try_get_xmp_packet      (GExiv2Metadata *self, GError **error);
+
 /**
  * gexiv2_metadata_get_xmp_packet:
  * @self: An instance of #GExiv2Metadata
  *
  * Returns: (transfer full) (allow-none): The currently-encoded XMP packet (see 
gexiv2_metadata_generate_xmp_packet).
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_xmp_packet() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_xmp_packet)
 gchar*                 gexiv2_metadata_get_xmp_packet          (GExiv2Metadata *self);
 
 /**
@@ -1057,6 +1245,43 @@ gint                     gexiv2_metadata_get_iso_speed           (GExiv2Metadata 
*self);
  * GPS functions
  */
 
+/**
+ * gexiv2_metadata_try_get_gps_longitude:
+ * @self: An instance of #GExiv2Metadata
+ * @longitude: (out): Variable to store the longitude value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Query the longitude stored in the GPS tags of @self
+ *
+ * Returns: (skip): Boolean success value
+ */
+gboolean               gexiv2_metadata_try_get_gps_longitude                   (GExiv2Metadata *self, 
gdouble *longitude, GError **error);
+
+/**
+ * gexiv2_metadata_try_get_gps_latitude:
+ * @self: An instance of #GExiv2Metadata
+ * @latitude: (out): Variable to store the latitude value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Query the latitude stored in the GPS tags of @self
+ *
+ * Returns: (skip): Boolean success value
+ */
+gboolean               gexiv2_metadata_try_get_gps_latitude                    (GExiv2Metadata *self, 
gdouble *latitude, GError **error);
+
+/**
+ * gexiv2_metadata_try_get_gps_altitude:
+ * @self: An instance of #GExiv2Metadata
+ * @altitude: (out): Variable to store the altitude value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Convenience function to query the altitude stored in the GPS tags of the
+ * image
+ *
+ * Returns: (skip): Boolean success value
+ */
+gboolean               gexiv2_metadata_try_get_gps_altitude            (GExiv2Metadata *self, gdouble 
*altitude, GError **error);
+
 /**
  * gexiv2_metadata_get_gps_longitude:
  * @self: An instance of #GExiv2Metadata
@@ -1065,7 +1290,10 @@ gint                     gexiv2_metadata_get_iso_speed           (GExiv2Metadata 
*self);
  * Query the longitude stored in the GPS tags of @self
  *
  * Returns: (skip): Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_gps_longitude() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_gps_longitude)
 gboolean               gexiv2_metadata_get_gps_longitude                       (GExiv2Metadata *self, 
gdouble *longitude);
 
 /**
@@ -1076,7 +1304,10 @@ gboolean         gexiv2_metadata_get_gps_longitude                       
(GExiv2Metadata *self, gdouble *lo
  * Query the latitude stored in the GPS tags of @self
  *
  * Returns: (skip): Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_gps_latitude() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_gps_latitude)
 gboolean               gexiv2_metadata_get_gps_latitude                        (GExiv2Metadata *self, 
gdouble *latitude);
 
 /**
@@ -1088,9 +1319,26 @@ gboolean         gexiv2_metadata_get_gps_latitude                        
(GExiv2Metadata *self, gdouble *lat
  * image
  *
  * Returns: (skip): Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_gps_altitude() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_gps_altitude)
 gboolean               gexiv2_metadata_get_gps_altitude                        (GExiv2Metadata *self, 
gdouble *altitude);
 
+/**
+ * gexiv2_metadata_try_get_gps_info:
+ * @self: An instance of #GExiv2Metadata
+ * @longitude: (out): Storage for longitude value
+ * @latitude: (out): Storage for latitude value
+ * @altitude: (out): Storage for altitude value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Convenience function to query all available GPS information at once.
+ *
+ * Returns: (skip): Boolean success value.
+ */
+gboolean               gexiv2_metadata_try_get_gps_info                        (GExiv2Metadata *self, 
gdouble *longitude, gdouble *latitude, gdouble *altitude, GError **error);
+
 /**
  * gexiv2_metadata_get_gps_info:
  * @self: An instance of #GExiv2Metadata
@@ -1101,9 +1349,28 @@ gboolean         gexiv2_metadata_get_gps_altitude                        
(GExiv2Metadata *self, gdouble *alt
  * Convenience function to query all available GPS information at once.
  *
  * Returns: (skip): Boolean success value.
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_gps_info() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_gps_info)
 gboolean               gexiv2_metadata_get_gps_info                            (GExiv2Metadata *self, 
gdouble *longitude, gdouble *latitude, gdouble *altitude);
 
+/**
+ * gexiv2_metadata_try_set_gps_info:
+ * @self: An instance of #GExiv2Metadata
+ * @longitude: Longitude value to set or replace current value
+ * @latitude: Latitude value to set or replace current value
+ * @altitude: Altitude value to set or replace current value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Convenience function to create a new set of simple GPS data. Warning: Will remove any other
+ * GPS information that is currently set. See gexiv2_metadata_update_gps_info() for
+ * just modifying the GPS data.
+ *
+ * Returns: (skip): Boolean success value.
+ */
+gboolean               gexiv2_metadata_try_set_gps_info                        (GExiv2Metadata *self, 
gdouble longitude, gdouble latitude, gdouble altitude, GError **error);
+
 /**
  * gexiv2_metadata_set_gps_info:
  * @self: An instance of #GExiv2Metadata
@@ -1116,9 +1383,28 @@ gboolean         gexiv2_metadata_get_gps_info                            
(GExiv2Metadata *self, gdouble *longit
  * just modifying the GPS data.
  *
  * Returns: (skip): Boolean success value.
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_gps_info() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_gps_info)
 gboolean               gexiv2_metadata_set_gps_info                            (GExiv2Metadata *self, 
gdouble longitude, gdouble latitude, gdouble altitude);
 
+/**
+ * gexiv2_metadata_try_update_gps_info:
+ * @self: An instance of #GExiv2Metadata
+ * @longitude: Longitude value to set or replace current value
+ * @latitude: Latitude value to set or replace current value
+ * @altitude: Altitude value to set or replace current value
+ * @error: (allow-none): A return location for a #GError or %NULL
+ *
+ * Convenience function to update longitude, latitude and altitude at once.
+ *
+ * Returns: (skip): Boolean success value.
+ *
+ * Since: 0.12.1
+ */
+gboolean               gexiv2_metadata_try_update_gps_info                     (GExiv2Metadata *self, 
gdouble longitude, gdouble latitude, gdouble altitude, GError **error);
+
 /**
  * gexiv2_metadata_update_gps_info:
  * @self: An instance of #GExiv2Metadata
@@ -1131,15 +1417,29 @@ gboolean                gexiv2_metadata_set_gps_info                            
(GExiv2Metadata *self, gdouble longitu
  * Returns: (skip): Boolean success value.
  *
  * Since: 0.12.1
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_update_gps_info() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_update_gps_info)
 gboolean               gexiv2_metadata_update_gps_info                         (GExiv2Metadata *self, 
gdouble longitude, gdouble latitude, gdouble altitude);
 
+/**
+ * gexiv2_metadata_try_delete_gps_info:
+ * @self: An instance of #GExiv2Metadata
+ *
+ * Removes all GPS metadata from the loaded image
+ */
+void                   gexiv2_metadata_try_delete_gps_info                     (GExiv2Metadata *self, GError 
**error);
+
 /**
  * gexiv2_metadata_delete_gps_info:
  * @self: An instance of #GExiv2Metadata
  *
  * Removes all GPS metadata from the loaded image
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_delete_gps_info() instead.
  */
+G_DEPRECATED_FOR(gexiv2_metadata_try_delete_gps_info)
 void                   gexiv2_metadata_delete_gps_info                 (GExiv2Metadata *self);
 
 /*
diff --git a/test/gexiv2-regression.c b/test/gexiv2-regression.c
index 947d806..f816c47 100644
--- a/test/gexiv2-regression.c
+++ b/test/gexiv2-regression.c
@@ -66,7 +66,7 @@ static void test_ggo_32 (void)
     g_assert_no_error(error);
     g_assert_true(result);
 
-    gexiv2_metadata_set_tag_long(meta, "Exif.Image.ImageLength", 1234);
+    gexiv2_metadata_try_set_tag_long(meta, "Exif.Image.ImageLength", 1234, NULL);
 
     pixel_height = gexiv2_metadata_get_metadata_pixel_height(meta);
     g_assert_cmpint(pixel_height, ==, 1234);
@@ -92,31 +92,31 @@ static void test_ggo_33 (void)
 
     /* Check all the width tags and check that they have the same value */
     gexiv2_metadata_set_metadata_pixel_width(meta, 1234);
-    pixels = gexiv2_metadata_get_tag_long(meta, "Exif.Photo.PixelXDimension");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Exif.Photo.PixelXDimension", NULL);
     g_assert_cmpint(pixels, ==, 1234);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Exif.Image.ImageWidth");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Exif.Image.ImageWidth", NULL);
     g_assert_cmpint(pixels, ==, 1234);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Xmp.tiff.ImageWidth");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Xmp.tiff.ImageWidth", NULL);
     g_assert_cmpint(pixels, ==, 1234);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Xmp.exif.PixelXDimension");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Xmp.exif.PixelXDimension", NULL);
     g_assert_cmpint(pixels, ==, 1234);
 
 
     /* Check all the height tags and check that they have the same value */
     gexiv2_metadata_set_metadata_pixel_height(meta, 4321);
-    pixels = gexiv2_metadata_get_tag_long(meta, "Exif.Photo.PixelYDimension");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Exif.Photo.PixelYDimension", NULL);
     g_assert_cmpint(pixels, ==, 4321);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Exif.Image.ImageLength");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Exif.Image.ImageLength", NULL);
     g_assert_cmpint(pixels, ==, 4321);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Xmp.tiff.ImageLength");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Xmp.tiff.ImageLength", NULL);
     g_assert_cmpint(pixels, ==, 4321);
 
-    pixels = gexiv2_metadata_get_tag_long(meta, "Xmp.exif.PixelYDimension");
+    pixels = gexiv2_metadata_try_get_tag_long(meta, "Xmp.exif.PixelYDimension", NULL);
     g_assert_cmpint(pixels, ==, 4321);
 
     g_clear_object(&meta);
@@ -156,7 +156,7 @@ static void test_bgo_775249(void)
     result = gexiv2_metadata_open_path(meta, SAMPLE_PATH "/CaorVN.jpeg", &error);
     g_assert_no_error(error);
     g_assert_true(result);
-    g_assert_true(gexiv2_metadata_get_gps_info(meta, &lon, &lat, &alt));
+    g_assert_true(gexiv2_metadata_try_get_gps_info(meta, &lon, &lat, &alt, NULL));
 
     g_assert_cmpfloat(lon, ==, -1.508425);
 
@@ -187,7 +187,7 @@ static void test_bgo_730136(void)
     g_assert_no_error(error);
     g_assert_true(result);
 
-    raw_tag = gexiv2_metadata_get_tag_raw (meta, "Exif.Image.Artist");
+    raw_tag = gexiv2_metadata_try_get_tag_raw (meta, "Exif.Image.Artist", NULL);
     g_assert_nonnull (raw_tag);
     g_assert_cmpmem (g_bytes_get_data(raw_tag, NULL), g_bytes_get_size(raw_tag),
                      test_bgo_730136_artist_data, sizeof(test_bgo_730136_artist_data));
@@ -285,10 +285,10 @@ static void test_ggo_45(void)
     g_assert_true(result);
 
     alt = 2200.0;
-    result = gexiv2_metadata_set_gps_info(meta, lon, lat, alt);
+    result = gexiv2_metadata_try_set_gps_info(meta, lon, lat, alt, NULL);
     g_assert_true(result);
 
-    result = gexiv2_metadata_get_gps_altitude(meta, &alt);
+    result = gexiv2_metadata_try_get_gps_altitude(meta, &alt, NULL);
     g_assert_true(result);
     g_assert_cmpfloat(fabs(alt - 2200.0), <= , 1e-5);
 


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