[vte] lib: Ensure no exceptions escape from the C API



commit dc6c348c3a4ef737f4f95cab373c7995a8a37e53
Author: Christian Persch <chpe src gnome org>
Date:   Wed May 27 21:17:04 2020 +0200

    lib: Ensure no exceptions escape from the C API
    
    https://gitlab.gnome.org/GNOME/vte/-/issues/185

 doc/reference/meson.build |    2 +-
 src/cxx-utils.hh          |   45 ++
 src/debug.cc              |    1 +
 src/debug.h               |    1 +
 src/glib-glue.hh          |   21 +-
 src/gobject-glue.hh       |   49 ++
 src/meson.build           |    2 +
 src/vte.cc                |   77 +--
 src/vte/vtedeprecated.h   |   47 +-
 src/vte/vteglobals.h      |    6 +-
 src/vte/vtemacros.h       |    9 +
 src/vte/vtepty.h          |   22 +-
 src/vte/vteregex.h        |   12 +-
 src/vte/vteterminal.h     |  188 +++----
 src/vte/vteversion.h.in   |    6 +-
 src/vteaccess.cc          |   67 ++-
 src/vtegtk.cc             | 1286 +++++++++++++++++++++++++++++++++++++--------
 src/vteinternal.hh        |   19 +-
 src/vtepty.cc             |  101 +++-
 src/vteptyinternal.hh     |    4 +-
 src/vteregex.cc           |   47 +-
 src/widget.cc             |   67 ++-
 src/widget.hh             |    2 +-
 23 files changed, 1603 insertions(+), 478 deletions(-)
---
diff --git a/doc/reference/meson.build b/doc/reference/meson.build
index 88cd671f..5af8fa3d 100644
--- a/doc/reference/meson.build
+++ b/doc/reference/meson.build
@@ -58,7 +58,7 @@ private_headers = [
 
 scan_args = [
   '--deprecated-guards="VTE_DISABLE_DEPRECATED"',
-  '--ignore-decorators=_VTE_GNUC_NONNULL\s*\([^)]*\)',
+  '--ignore-decorators=_VTE_GNUC_NONNULL\s*\([^)]*\)|_VTE_CXX_NOEXCEPT',
 ]
 
 glib_prefix = glib_dep.get_pkgconfig_variable('prefix')
diff --git a/src/cxx-utils.hh b/src/cxx-utils.hh
new file mode 100644
index 00000000..bb831165
--- /dev/null
+++ b/src/cxx-utils.hh
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2020 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <exception>
+#include <type_traits>
+
+namespace vte {
+
+// This is like std::clamp, except that it doesn't throw when
+// max_v<min_v, but instead returns min_v in that case.
+template<typename T>
+constexpr inline T const&
+clamp(T const& v,
+      T const& min_v,
+      T const& max_v)
+{
+        return std::max(std::min(v, max_v), min_v);
+}
+
+#ifdef VTE_DEBUG
+void log_exception(char const* func = __builtin_FUNCTION(),
+                   char const* filename = __builtin_FILE(),
+                   int const line = __builtin_LINE()) noexcept;
+#else
+inline void log_exception() noexcept { }
+#endif
+
+} // namespace vte
diff --git a/src/debug.cc b/src/debug.cc
index 5b1b0d8a..857a40b7 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -60,6 +60,7 @@ _vte_debug_init(void)
     { "ringview",     VTE_DEBUG_RINGVIEW     },
     { "bidi",         VTE_DEBUG_BIDI         },
     { "conversion",   VTE_DEBUG_CONVERSION   },
+    { "exceptions",   VTE_DEBUG_EXCEPTIONS   },
   };
 
   _vte_debug_flags = g_parse_debug_string (g_getenv("VTE_DEBUG"),
diff --git a/src/debug.h b/src/debug.h
index 4fd498a9..90be5c5f 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -67,6 +67,7 @@ typedef enum {
         VTE_DEBUG_RINGVIEW      = 1 << 27,
         VTE_DEBUG_BIDI          = 1 << 28,
         VTE_DEBUG_CONVERSION    = 1 << 29,
+        VTE_DEBUG_EXCEPTIONS    = 1 << 30,
 } VteDebugFlags;
 
 void _vte_debug_init(void);
diff --git a/src/glib-glue.hh b/src/glib-glue.hh
index ae1ead88..dd317db9 100644
--- a/src/glib-glue.hh
+++ b/src/glib-glue.hh
@@ -24,6 +24,8 @@
 
 #include <glib.h>
 
+#include "cxx-utils.hh"
+
 namespace vte::glib {
 
 template <typename T, typename D, D d>
@@ -219,9 +221,16 @@ private:
         guint m_source_id{0};
         bool m_rescheduled{false};
 
-        bool dispatch() noexcept {
+        bool dispatch() noexcept
+        {
                 auto const id = m_source_id;
-                auto const rv = m_callback();
+
+                auto rv = false;
+                try {
+                        rv = m_callback();
+                } catch (...) {
+                        vte::log_exception();
+                }
 
                 /* The Timer may have been re-scheduled or removed from within
                  * the callback. In this case, the callback must return false!
@@ -264,4 +273,12 @@ private:
         }
 };
 
+bool set_error_from_exception(GError** error
+#ifdef VTE_DEBUG
+                              , char const* func = __builtin_FUNCTION()
+                              , char const* filename = __builtin_FILE()
+                              , int const line = __builtin_LINE()
+#endif
+                              ) noexcept;
+
 } // namespace vte::glib
diff --git a/src/gobject-glue.hh b/src/gobject-glue.hh
new file mode 100644
index 00000000..f53d472a
--- /dev/null
+++ b/src/gobject-glue.hh
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2020 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+namespace vte::glib {
+
+class FreezeObjectNotify {
+public:
+        explicit FreezeObjectNotify(void* object) noexcept
+                : m_object{G_OBJECT(object)}
+        {
+                g_object_freeze_notify(m_object);
+        }
+
+        ~FreezeObjectNotify() noexcept
+        {
+                g_object_thaw_notify(m_object);
+        }
+
+        FreezeObjectNotify() = delete;
+        FreezeObjectNotify(FreezeObjectNotify const&) = delete;
+        FreezeObjectNotify(FreezeObjectNotify&&) = delete;
+        FreezeObjectNotify& operator=(FreezeObjectNotify const&) = delete;
+        FreezeObjectNotify& operator=(FreezeObjectNotify&&) = delete;
+
+        auto get() const noexcept { return m_object; }
+
+private:
+        GObject* m_object;
+}; // class FreezeObjectNotify
+
+} // namespace vte::glib
diff --git a/src/meson.build b/src/meson.build
index f25b425d..1fe64810 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -103,6 +103,8 @@ libvte_common_sources = debug_sources + glib_glue_sources + libc_glue_sources +
   'chunk.cc',
   'chunk.hh',
   'color-triple.hh',
+  'cxx-utils.hh',
+  'gobject-glue.hh',
   'keymap.cc',
   'keymap.h',
   'missing.cc',
diff --git a/src/vte.cc b/src/vte.cc
index 7ec837b6..197aaa00 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -64,6 +64,8 @@
 #include "marshal.h"
 #include "vtepty.h"
 #include "vtegtk.hh"
+#include "cxx-utils.hh"
+#include "gobject-glue.hh"
 
 #ifdef WITH_A11Y
 #include "vteaccess.h"
@@ -96,8 +98,8 @@ static void add_process_timeout(vte::terminal::Terminal* that);
 static void add_update_timeout(vte::terminal::Terminal* that);
 static void remove_update_timeout(vte::terminal::Terminal* that);
 
-static gboolean process_timeout (gpointer data);
-static gboolean update_timeout (gpointer data);
+static gboolean process_timeout (gpointer data) noexcept;
+static gboolean update_timeout (gpointer data) noexcept;
 static cairo_region_t *vte_cairo_get_clip_region (cairo_t *cr);
 
 /* these static variables are guarded by the GDK mutex */
@@ -688,7 +690,7 @@ Terminal::invalidate_cursor_once(bool periodic)
 /* Invalidate the cursor repeatedly. */
 // FIXMEchpe this continually adds and removes the blink timeout. Find a better solution
 bool
-Terminal::cursor_blink_timer_callback() noexcept
+Terminal::cursor_blink_timer_callback()
 {
        m_cursor_blink_state = !m_cursor_blink_state;
        m_cursor_blink_time += m_cursor_blink_cycle;
@@ -834,7 +836,7 @@ Terminal::queue_child_exited()
 }
 
 bool
-Terminal::child_exited_eos_wait_callback() noexcept
+Terminal::child_exited_eos_wait_callback()
 {
         /* If we get this callback, there has been some time elapsed
          * after child-exited, but no EOS yet. This happens for example
@@ -1813,7 +1815,7 @@ Terminal::emit_adjustment_changed()
 
                 auto vadjustment = m_vadjustment.get();
 
-                g_object_freeze_notify(G_OBJECT(vadjustment));
+                auto const freezer = vte::glib::FreezeObjectNotify{vadjustment};
 
                v = _vte_ring_delta (m_screen->row_data);
                 current = gtk_adjustment_get_lower(vadjustment);
@@ -1869,8 +1871,6 @@ Terminal::emit_adjustment_changed()
                        changed = true;
                }
 
-                g_object_thaw_notify(G_OBJECT(vadjustment));
-
                if (changed)
                        _vte_debug_print(VTE_DEBUG_SIGNALS,
                                        "Emitting adjustment_changed.\n");
@@ -3086,11 +3086,16 @@ static void
 reaper_child_exited_cb(VteReaper *reaper,
                        int ipid,
                        int status,
-                       vte::terminal::Terminal* that)
+                       vte::terminal::Terminal* that) noexcept
+try
 {
         that->child_watch_done(pid_t{ipid}, status);
         // @that might be destroyed at this point
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 void
 Terminal::child_watch_done(pid_t pid,
@@ -3276,8 +3281,7 @@ Terminal::watch_child (pid_t child_pid)
         if (!pty())
                 return;
 
-        GObject *object = G_OBJECT(m_terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{m_terminal};
 
         /* Set this as the child's pid. */
         m_pty_pid = child_pid;
@@ -3301,8 +3305,6 @@ Terminal::watch_child (pid_t child_pid)
         }
 
         /* FIXMEchpe: call set_size() here? */
-
-        g_object_thaw_notify(object);
 }
 
 /* Reset the input method context. */
@@ -6725,7 +6727,7 @@ Terminal::select_all()
 }
 
 bool
-Terminal::mouse_autoscroll_timer_callback() noexcept
+Terminal::mouse_autoscroll_timer_callback()
 {
        bool extend = false;
        long x, y, xmax, ymax;
@@ -7595,10 +7597,15 @@ Terminal::set_size(long columns,
 
 /* Redraw the widget. */
 static void
-vte_terminal_vadjustment_value_changed_cb(vte::terminal::Terminal* that)
+vte_terminal_vadjustment_value_changed_cb(vte::terminal::Terminal* that) noexcept
+try
 {
         that->vadjustment_value_changed();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 void
 Terminal::vadjustment_value_changed()
@@ -8142,7 +8149,7 @@ Terminal::determine_cursor_colors(VteCell const* cell,
 
 // FIXMEchpe this constantly removes and reschedules the timer. improve this!
 bool
-Terminal::text_blink_timer_callback() noexcept
+Terminal::text_blink_timer_callback()
 {
         invalidate_all();
         return false; /* don't run again */
@@ -9824,8 +9831,7 @@ Terminal::reset(bool clear_tabstops,
         if (from_api && !m_input_enabled)
                 return;
 
-        GObject *object = G_OBJECT(m_terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{m_terminal};
 
         m_bell_pending = false;
 
@@ -9918,8 +9924,6 @@ Terminal::reset(bool clear_tabstops,
 
         /* Reset XTerm window controls */
         m_xterm_wm_iconified = false;
-
-        g_object_thaw_notify(object);
 }
 
 void
@@ -10134,8 +10138,7 @@ Terminal::start_processing()
 void
 Terminal::emit_pending_signals()
 {
-       GObject *object = G_OBJECT(m_terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{m_terminal};
 
        emit_adjustment_changed();
 
@@ -10145,8 +10148,8 @@ Terminal::emit_pending_signals()
 
                         _vte_debug_print(VTE_DEBUG_SIGNALS,
                                          "Emitting `window-title-changed'.\n");
-                        g_signal_emit(object, signals[SIGNAL_WINDOW_TITLE_CHANGED], 0);
-                        g_object_notify_by_pspec(object, pspecs[PROP_WINDOW_TITLE]);
+                        g_signal_emit(freezer.get(), signals[SIGNAL_WINDOW_TITLE_CHANGED], 0);
+                        g_object_notify_by_pspec(freezer.get(), pspecs[PROP_WINDOW_TITLE]);
                 }
 
                 m_window_title_pending.clear();
@@ -10159,8 +10162,8 @@ Terminal::emit_pending_signals()
 
                         _vte_debug_print(VTE_DEBUG_SIGNALS,
                                          "Emitting `current-directory-uri-changed'.\n");
-                        g_signal_emit(object, signals[SIGNAL_CURRENT_DIRECTORY_URI_CHANGED], 0);
-                        g_object_notify_by_pspec(object, pspecs[PROP_CURRENT_DIRECTORY_URI]);
+                        g_signal_emit(freezer.get(), signals[SIGNAL_CURRENT_DIRECTORY_URI_CHANGED], 0);
+                        g_object_notify_by_pspec(freezer.get(), pspecs[PROP_CURRENT_DIRECTORY_URI]);
                 }
 
                 m_current_directory_uri_pending.clear();
@@ -10173,8 +10176,8 @@ Terminal::emit_pending_signals()
 
                         _vte_debug_print(VTE_DEBUG_SIGNALS,
                                          "Emitting `current-file-uri-changed'.\n");
-                        g_signal_emit(object, signals[SIGNAL_CURRENT_FILE_URI_CHANGED], 0);
-                        g_object_notify_by_pspec(object, pspecs[PROP_CURRENT_FILE_URI]);
+                        g_signal_emit(freezer.get(), signals[SIGNAL_CURRENT_FILE_URI_CHANGED], 0);
+                        g_object_notify_by_pspec(freezer.get(), pspecs[PROP_CURRENT_FILE_URI]);
                 }
 
                 m_current_file_uri_pending.clear();
@@ -10186,7 +10189,7 @@ Terminal::emit_pending_signals()
         if (m_cursor_moved_pending) {
                 _vte_debug_print(VTE_DEBUG_SIGNALS,
                                  "Emitting `cursor-moved'.\n");
-                g_signal_emit(object, signals[SIGNAL_CURSOR_MOVED], 0);
+                g_signal_emit(freezer.get(), signals[SIGNAL_CURSOR_MOVED], 0);
                 m_cursor_moved_pending = false;
         }
         if (m_text_modified_flag) {
@@ -10232,8 +10235,6 @@ Terminal::emit_pending_signals()
                 m_bell_pending = false;
         }
 
-        g_object_thaw_notify(object);
-
         auto const eos = m_eos_pending;
         if (m_eos_pending) {
                 queue_eof();
@@ -10292,7 +10293,8 @@ Terminal::process(bool emit_adj_changed)
  * It makes sure initial output is never delayed by more than DISPLAY_TIMEOUT
  */
 static gboolean
-process_timeout (gpointer data)
+process_timeout (gpointer data) noexcept
+try
 {
        GList *l, *next;
        gboolean again;
@@ -10347,6 +10349,11 @@ process_timeout (gpointer data)
 
        return again;
 }
+catch (...)
+{
+        vte::log_exception();
+        return true; // false?
+}
 
 bool
 Terminal::invalidate_dirty_rects_and_process_updates()
@@ -10445,7 +10452,8 @@ update_repeat_timeout (gpointer data)
 }
 
 static gboolean
-update_timeout (gpointer data)
+update_timeout (gpointer data) noexcept
+try
 {
        GList *l, *next;
 
@@ -10485,6 +10493,11 @@ update_timeout (gpointer data)
 
        return FALSE;
 }
+catch (...)
+{
+        vte::log_exception();
+        return true; // false?
+}
 
 bool
 Terminal::write_contents_sync (GOutputStream *stream,
diff --git a/src/vte/vtedeprecated.h b/src/vte/vtedeprecated.h
index 6f6f56c9..e13debf3 100644
--- a/src/vte/vtedeprecated.h
+++ b/src/vte/vtedeprecated.h
@@ -25,6 +25,7 @@
 
 #include "vteterminal.h"
 #include "vtepty.h"
+#include "vtemacros.h"
 
 #ifndef VTE_DISABLE_DEPRECATION_WARNINGS
 #define _VTE_DEPRECATED G_DEPRECATED
@@ -38,25 +39,25 @@ _VTE_DEPRECATED
 _VTE_PUBLIC
 int vte_terminal_match_add_gregex(VteTerminal *terminal,
                                   GRegex *gregex,
-                                  GRegexMatchFlags gflags) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                  GRegexMatchFlags gflags) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_match_set_cursor(VteTerminal *terminal,
                                    int tag,
-                                   GdkCursor *cursor) _VTE_GNUC_NONNULL(1);
+                                   GdkCursor *cursor) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_match_set_cursor_type(VteTerminal *terminal,
                                        int tag,
-                                        GdkCursorType cursor_type) _VTE_GNUC_NONNULL(1);
+                                        GdkCursorType cursor_type) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 char *vte_terminal_match_check(VteTerminal *terminal,
                               glong column, glong row,
-                              int *tag) _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+                              int *tag) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
@@ -65,17 +66,17 @@ gboolean vte_terminal_event_check_gregex_simple(VteTerminal *terminal,
                                                 GRegex **regexes,
                                                 gsize n_regexes,
                                                 GRegexMatchFlags match_flags,
-                                                char **matches) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                                char **matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void      vte_terminal_search_set_gregex      (VteTerminal *terminal,
                                               GRegex      *gregex,
-                                               GRegexMatchFlags gflags) _VTE_GNUC_NONNULL(1);
+                                               GRegexMatchFlags gflags) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-GRegex   *vte_terminal_search_get_gregex      (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+GRegex   *vte_terminal_search_get_gregex      (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
@@ -89,78 +90,78 @@ gboolean vte_terminal_spawn_sync(VteTerminal *terminal,
                                  gpointer child_setup_data,
                                  GPid *child_pid /* out */,
                                  GCancellable *cancellable,
-                                 GError **error) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(4);
+                                 GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(4);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-void vte_pty_close (VtePty *pty) _VTE_GNUC_NONNULL(1);
+void vte_pty_close (VtePty *pty) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-void vte_terminal_copy_clipboard(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_copy_clipboard(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_get_geometry_hints(VteTerminal *terminal,
                                      GdkGeometry *hints,
                                      int min_rows,
-                                     int min_columns) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                     int min_columns) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_set_geometry_hints_for_window(VteTerminal *terminal,
-                                                GtkWindow *window) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                                GtkWindow *window) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-const char *vte_terminal_get_icon_title(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_icon_title(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 gboolean vte_terminal_set_encoding(VteTerminal *terminal,
                                    const char *codeset,
-                                   GError **error) _VTE_GNUC_NONNULL(1);
+                                   GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-const char *vte_terminal_get_encoding(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_encoding(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 char *vte_terminal_get_text_include_trailing_spaces(VteTerminal *terminal,
                                                    VteSelectionFunc is_selected,
                                                    gpointer user_data,
-                                                   GArray *attributes) _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+                                                   GArray *attributes) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_set_rewrap_on_resize(VteTerminal *terminal,
-                                       gboolean rewrap) _VTE_GNUC_NONNULL(1);
+                                       gboolean rewrap) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_DEPRECATED
 _VTE_PUBLIC
-gboolean vte_terminal_get_rewrap_on_resize(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_rewrap_on_resize(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_set_allow_bold(VteTerminal *terminal,
-                                 gboolean allow_bold) _VTE_GNUC_NONNULL(1);
+                                 gboolean allow_bold) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_DEPRECATED
 _VTE_PUBLIC
-gboolean vte_terminal_get_allow_bold(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_allow_bold(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
 void vte_terminal_feed_child_binary(VteTerminal *terminal,
                                     const guint8 *data,
-                                    gsize length) _VTE_GNUC_NONNULL(1);
+                                    gsize length) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-char **vte_get_encodings(gboolean include_aliases);
+char **vte_get_encodings(gboolean include_aliases) _VTE_CXX_NOEXCEPT;
 
 _VTE_DEPRECATED
 _VTE_PUBLIC
-gboolean vte_get_encoding_supported(const char *encoding);
+gboolean vte_get_encoding_supported(const char *encoding) _VTE_CXX_NOEXCEPT;
 
 G_END_DECLS
 
diff --git a/src/vte/vteglobals.h b/src/vte/vteglobals.h
index a2add132..34b44bfb 100644
--- a/src/vte/vteglobals.h
+++ b/src/vte/vteglobals.h
@@ -26,16 +26,16 @@
 G_BEGIN_DECLS
 
 _VTE_PUBLIC
-char *vte_get_user_shell(void);
+char *vte_get_user_shell(void) _VTE_CXX_NOEXCEPT;
 
 _VTE_PUBLIC
-const char *vte_get_features (void);
+const char *vte_get_features (void) _VTE_CXX_NOEXCEPT;
 
 #define VTE_TEST_FLAGS_NONE (G_GUINT64_CONSTANT(0))
 #define VTE_TEST_FLAGS_ALL (~G_GUINT64_CONSTANT(0))
 
 _VTE_PUBLIC
-void vte_set_test_flags(guint64 flags);
+void vte_set_test_flags(guint64 flags) _VTE_CXX_NOEXCEPT;
 
 G_END_DECLS
 
diff --git a/src/vte/vtemacros.h b/src/vte/vtemacros.h
index 3f8acf51..d2a98ecc 100644
--- a/src/vte/vtemacros.h
+++ b/src/vte/vtemacros.h
@@ -41,4 +41,13 @@
 
 #define _VTE_PUBLIC __attribute__((__visibility__("default"))) extern
 
+#if defined(VTE_COMPILATION) && defined(__cplusplus)
+#if __cplusplus >= 201103L
+#define _VTE_CXX_NOEXCEPT noexcept
+#endif
+#endif
+#ifndef _VTE_CXX_NOEXCEPT
+#define _VTE_CXX_NOEXCEPT
+#endif
+
 #endif /* __VTE_VTE_MACROS_H__ */
diff --git a/src/vte/vtepty.h b/src/vte/vtepty.h
index f811c5b2..875119b7 100644
--- a/src/vte/vtepty.h
+++ b/src/vte/vtepty.h
@@ -35,7 +35,7 @@ G_BEGIN_DECLS
 #define VTE_SPAWN_REQUIRE_SYSTEMD_SCOPE (1 << 27)
 
 _VTE_PUBLIC
-GQuark vte_pty_error_quark (void);
+GQuark vte_pty_error_quark (void) _VTE_CXX_NOEXCEPT;
 
 /**
  * VTE_PTY_ERROR:
@@ -63,35 +63,35 @@ GType vte_pty_get_type (void);
 _VTE_PUBLIC
 VtePty *vte_pty_new_sync (VtePtyFlags flags,
                           GCancellable *cancellable,
-                          GError **error);
+                          GError **error) _VTE_CXX_NOEXCEPT;
 
 _VTE_PUBLIC
 VtePty *vte_pty_new_foreign_sync (int fd,
                                   GCancellable *cancellable,
-                                  GError **error);
+                                  GError **error) _VTE_CXX_NOEXCEPT;
 
 _VTE_PUBLIC
-int vte_pty_get_fd (VtePty *pty) _VTE_GNUC_NONNULL(1);
+int vte_pty_get_fd (VtePty *pty) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
-void vte_pty_child_setup (VtePty *pty) _VTE_GNUC_NONNULL(1);
+void vte_pty_child_setup (VtePty *pty) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 gboolean vte_pty_get_size (VtePty *pty,
                            int *rows,
                            int *columns,
-                           GError **error) _VTE_GNUC_NONNULL(1);
+                           GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 gboolean vte_pty_set_size (VtePty *pty,
                            int rows,
                            int columns,
-                           GError **error) _VTE_GNUC_NONNULL(1);
+                           GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 gboolean vte_pty_set_utf8 (VtePty *pty,
                            gboolean utf8,
-                           GError **error) _VTE_GNUC_NONNULL(1);
+                           GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VtePty, g_object_unref)
 
@@ -107,7 +107,7 @@ void vte_pty_spawn_async(VtePty *pty,
                          int timeout,
                          GCancellable *cancellable,
                          GAsyncReadyCallback callback,
-                         gpointer user_data) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(3);
+                         gpointer user_data) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(3);
 
 _VTE_PUBLIC
 void vte_pty_spawn_with_fds_async(VtePty *pty,
@@ -125,12 +125,12 @@ void vte_pty_spawn_with_fds_async(VtePty *pty,
                                   int timeout,
                                   GCancellable *cancellable,
                                   GAsyncReadyCallback callback,
-                                  gpointer user_data) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(3);
+                                  gpointer user_data) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(3);
 
 gboolean vte_pty_spawn_finish(VtePty *pty,
                               GAsyncResult *result,
                               GPid *child_pid /* out */,
-                              GError **error) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                              GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
 
 G_END_DECLS
 
diff --git a/src/vte/vteregex.h b/src/vte/vteregex.h
index 9001d443..e6f073a3 100644
--- a/src/vte/vteregex.h
+++ b/src/vte/vteregex.h
@@ -45,34 +45,34 @@ GQuark vte_regex_error_quark (void);
 #define VTE_REGEX_FLAGS_DEFAULT (0x00080000u | 0x40000000u | 0x00100000u)
 
 _VTE_PUBLIC
-VteRegex *vte_regex_ref      (VteRegex *regex) _VTE_GNUC_NONNULL(1);
+VteRegex *vte_regex_ref      (VteRegex *regex) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
-VteRegex *vte_regex_unref    (VteRegex *regex) _VTE_GNUC_NONNULL(1);
+VteRegex *vte_regex_unref    (VteRegex *regex) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 VteRegex *vte_regex_new_for_match (const char *pattern,
                                    gssize      pattern_length,
                                    guint32     flags,
-                                   GError    **error) _VTE_GNUC_NONNULL(1);
+                                   GError    **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 VteRegex *vte_regex_new_for_search (const char *pattern,
                                     gssize      pattern_length,
                                     guint32     flags,
-                                    GError    **error) _VTE_GNUC_NONNULL(1);
+                                    GError    **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 gboolean  vte_regex_jit     (VteRegex *regex,
                              guint32   flags,
-                             GError  **error) _VTE_GNUC_NONNULL(1);
+                             GError  **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 char *vte_regex_substitute(VteRegex *regex,
                            const char *subject,
                            const char *replacement,
                            guint32 flags,
-                           GError **error) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) _VTE_GNUC_NONNULL(3) 
G_GNUC_MALLOC;
+                           GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) 
_VTE_GNUC_NONNULL(3) G_GNUC_MALLOC;
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VteRegex, vte_regex_unref)
 
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index 812e4476..bdede897 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -128,17 +128,17 @@ _VTE_PUBLIC
 GType vte_terminal_get_type(void);
 
 _VTE_PUBLIC
-GtkWidget *vte_terminal_new(void);
+GtkWidget *vte_terminal_new(void) _VTE_CXX_NOEXCEPT;
 
 _VTE_PUBLIC
 VtePty *vte_terminal_pty_new_sync (VteTerminal *terminal,
                                    VtePtyFlags flags,
                                    GCancellable *cancellable,
-                                   GError **error) _VTE_GNUC_NONNULL(1);
+                                   GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_watch_child (VteTerminal *terminal,
-                               GPid child_pid) _VTE_GNUC_NONNULL(1);
+                               GPid child_pid) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 typedef void (* VteTerminalSpawnAsyncCallback) (VteTerminal *terminal,
                                                 GPid pid,
@@ -158,7 +158,7 @@ void vte_terminal_spawn_async(VteTerminal *terminal,
                               int timeout,
                               GCancellable *cancellable,
                               VteTerminalSpawnAsyncCallback callback,
-                              gpointer user_data) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(4);
+                              gpointer user_data) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(4);
 
 _VTE_PUBLIC
 void vte_terminal_spawn_with_fds_async(VteTerminal* terminal,
@@ -177,196 +177,196 @@ void vte_terminal_spawn_with_fds_async(VteTerminal* terminal,
                                        int timeout,
                                        GCancellable* cancellable,
                                        VteTerminalSpawnAsyncCallback callback,
-                                       gpointer user_data) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(4);
+                                       gpointer user_data) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(4);
 
 /* Send data to the terminal to display, or to the terminal's forked command
  * to handle in some way.  If it's 'cat', they should be the same. */
 _VTE_PUBLIC
 void vte_terminal_feed(VteTerminal *terminal,
                        const char *data,
-                       gssize length) _VTE_GNUC_NONNULL(1);
+                       gssize length) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_feed_child(VteTerminal *terminal,
                              const char *text,
-                             gssize length) _VTE_GNUC_NONNULL(1);
+                             gssize length) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Copy currently-selected text to the clipboard, or from the clipboard to
  * the terminal. */
 _VTE_PUBLIC
 void vte_terminal_copy_clipboard_format(VteTerminal *terminal,
-                                        VteFormat format) _VTE_GNUC_NONNULL(1);
+                                        VteFormat format) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_paste_clipboard(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_paste_clipboard(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_copy_primary(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_copy_primary(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_paste_primary(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_paste_primary(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_select_all(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_select_all(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_unselect_all(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_unselect_all(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* By-word selection */
 _VTE_PUBLIC
 void vte_terminal_set_word_char_exceptions(VteTerminal *terminal,
-                                           const char *exceptions) _VTE_GNUC_NONNULL(1);
+                                           const char *exceptions) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-const char *vte_terminal_get_word_char_exceptions(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_word_char_exceptions(VteTerminal *terminal) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 
 /* Set the terminal's size. */
 _VTE_PUBLIC
 void vte_terminal_set_size(VteTerminal *terminal,
-                          glong columns, glong rows) _VTE_GNUC_NONNULL(1);
+                          glong columns, glong rows) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_font_scale(VteTerminal *terminal,
-                                 gdouble scale) _VTE_GNUC_NONNULL(1);
+                                 gdouble scale) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gdouble vte_terminal_get_font_scale(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gdouble vte_terminal_get_font_scale(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_cell_width_scale(VteTerminal *terminal,
-                                       double scale) _VTE_GNUC_NONNULL(1);
+                                       double scale) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-double vte_terminal_get_cell_width_scale(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+double vte_terminal_get_cell_width_scale(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_cell_height_scale(VteTerminal *terminal,
-                                        double scale) _VTE_GNUC_NONNULL(1);
+                                        double scale) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-double vte_terminal_get_cell_height_scale(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+double vte_terminal_get_cell_height_scale(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set various on-off settings. */
 _VTE_PUBLIC
 void vte_terminal_set_text_blink_mode(VteTerminal *terminal,
-                                      VteTextBlinkMode text_blink_mode) _VTE_GNUC_NONNULL(1);
+                                      VteTextBlinkMode text_blink_mode) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-VteTextBlinkMode vte_terminal_get_text_blink_mode(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+VteTextBlinkMode vte_terminal_get_text_blink_mode(VteTerminal *terminal) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_audible_bell(VteTerminal *terminal,
-                                   gboolean is_audible) _VTE_GNUC_NONNULL(1);
+                                   gboolean is_audible) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_audible_bell(VteTerminal *terminal);
+gboolean vte_terminal_get_audible_bell(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_scroll_on_output(VteTerminal *terminal,
-                                       gboolean scroll) _VTE_GNUC_NONNULL(1);
+                                       gboolean scroll) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_scroll_on_output(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_scroll_on_output(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_scroll_on_keystroke(VteTerminal *terminal,
-                                         gboolean scroll);
+                                         gboolean scroll) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set the color scheme. */
 _VTE_PUBLIC
 void vte_terminal_set_color_bold(VteTerminal *terminal,
-                                 const GdkRGBA *bold) _VTE_GNUC_NONNULL(1);
+                                 const GdkRGBA *bold) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_color_foreground(VteTerminal *terminal,
-                                       const GdkRGBA *foreground) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                       const GdkRGBA *foreground) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 _VTE_PUBLIC
 void vte_terminal_set_color_background(VteTerminal *terminal,
-                                       const GdkRGBA *background) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                       const GdkRGBA *background) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 _VTE_PUBLIC
 void vte_terminal_set_color_cursor(VteTerminal *terminal,
-                                   const GdkRGBA *cursor_background) _VTE_GNUC_NONNULL(1);
+                                   const GdkRGBA *cursor_background) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_color_cursor_foreground(VteTerminal *terminal,
-                                              const GdkRGBA *cursor_foreground) _VTE_GNUC_NONNULL(1);
+                                              const GdkRGBA *cursor_foreground) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_color_highlight(VteTerminal *terminal,
-                                      const GdkRGBA *highlight_background) _VTE_GNUC_NONNULL(1);
+                                      const GdkRGBA *highlight_background) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_color_highlight_foreground(VteTerminal *terminal,
-                                                 const GdkRGBA *highlight_foreground) _VTE_GNUC_NONNULL(1);
+                                                 const GdkRGBA *highlight_foreground) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_colors(VteTerminal *terminal,
                              const GdkRGBA *foreground,
                              const GdkRGBA *background,
                              const GdkRGBA *palette,
-                             gsize palette_size) _VTE_GNUC_NONNULL(1);
+                             gsize palette_size) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
-void vte_terminal_set_default_colors(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_set_default_colors(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set whether or not the cursor blinks. */
 _VTE_PUBLIC
 void vte_terminal_set_cursor_blink_mode(VteTerminal *terminal,
-                                       VteCursorBlinkMode mode) _VTE_GNUC_NONNULL(1);
+                                       VteCursorBlinkMode mode) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-VteCursorBlinkMode vte_terminal_get_cursor_blink_mode(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+VteCursorBlinkMode vte_terminal_get_cursor_blink_mode(VteTerminal *terminal) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 
 /* Set cursor shape */
 _VTE_PUBLIC
 void vte_terminal_set_cursor_shape(VteTerminal *terminal,
-                                  VteCursorShape shape) _VTE_GNUC_NONNULL(1);
+                                  VteCursorShape shape) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-VteCursorShape vte_terminal_get_cursor_shape(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+VteCursorShape vte_terminal_get_cursor_shape(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set the number of scrollback lines, above or at an internal minimum. */
 _VTE_PUBLIC
 void vte_terminal_set_scrollback_lines(VteTerminal *terminal,
-                                       glong lines) _VTE_GNUC_NONNULL(1);
+                                       glong lines) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-glong vte_terminal_get_scrollback_lines(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+glong vte_terminal_get_scrollback_lines(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set or retrieve the current font. */
 _VTE_PUBLIC
 void vte_terminal_set_font(VteTerminal *terminal,
-                          const PangoFontDescription *font_desc) _VTE_GNUC_NONNULL(1);
+                          const PangoFontDescription *font_desc) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-const PangoFontDescription *vte_terminal_get_font(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const PangoFontDescription *vte_terminal_get_font(VteTerminal *terminal) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_bold_is_bright(VteTerminal *terminal,
-                                     gboolean bold_is_bright) _VTE_GNUC_NONNULL(1);
+                                     gboolean bold_is_bright) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_bold_is_bright(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_bold_is_bright(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_allow_hyperlink(VteTerminal *terminal,
-                                      gboolean allow_hyperlink) _VTE_GNUC_NONNULL(1);
+                                      gboolean allow_hyperlink) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_allow_hyperlink(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_allow_hyperlink(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Check if the terminal is the current selection owner. */
 _VTE_PUBLIC
-gboolean vte_terminal_get_has_selection(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_has_selection(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Set what happens when the user strikes backspace or delete. */
 _VTE_PUBLIC
 void vte_terminal_set_backspace_binding(VteTerminal *terminal,
-                                       VteEraseBinding binding) _VTE_GNUC_NONNULL(1);
+                                       VteEraseBinding binding) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_set_delete_binding(VteTerminal *terminal,
-                                    VteEraseBinding binding) _VTE_GNUC_NONNULL(1);
+                                    VteEraseBinding binding) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* BiDi and shaping */
 _VTE_PUBLIC
 void vte_terminal_set_enable_bidi(VteTerminal *terminal,
-                                  gboolean enable_bidi) _VTE_GNUC_NONNULL(1);
+                                  gboolean enable_bidi) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_enable_bidi(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_enable_bidi(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_enable_shaping(VteTerminal *terminal,
-                                     gboolean enable_shaping) _VTE_GNUC_NONNULL(1);
+                                     gboolean enable_shaping) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_enable_shaping(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_enable_shaping(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Manipulate the autohide setting. */
 _VTE_PUBLIC
 void vte_terminal_set_mouse_autohide(VteTerminal *terminal,
-                                     gboolean setting) _VTE_GNUC_NONNULL(1);
+                                     gboolean setting) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_mouse_autohide(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_mouse_autohide(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Reset the terminal, optionally clearing the tab stops and line history. */
 _VTE_PUBLIC
 void vte_terminal_reset(VteTerminal *terminal,
                         gboolean clear_tabstops,
-                       gboolean clear_history) _VTE_GNUC_NONNULL(1);
+                       gboolean clear_history) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Read the contents of the terminal, using a callback function to determine
  * if a particular location on the screen (0-based) is interesting enough to
@@ -378,39 +378,39 @@ _VTE_PUBLIC
 char *vte_terminal_get_text(VteTerminal *terminal,
                            VteSelectionFunc is_selected,
                            gpointer user_data,
-                           GArray *attributes) _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+                           GArray *attributes) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
 _VTE_PUBLIC
 char *vte_terminal_get_text_range(VteTerminal *terminal,
                                  glong start_row, glong start_col,
                                  glong end_row, glong end_col,
                                  VteSelectionFunc is_selected,
                                  gpointer user_data,
-                                 GArray *attributes) _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+                                 GArray *attributes) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
 _VTE_PUBLIC
 void vte_terminal_get_cursor_position(VteTerminal *terminal,
                                      glong *column,
-                                      glong *row) _VTE_GNUC_NONNULL(1);
+                                      glong *row) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 char *vte_terminal_hyperlink_check_event(VteTerminal *terminal,
-                                         GdkEvent *event) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) 
G_GNUC_MALLOC;
+                                         GdkEvent *event) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2) G_GNUC_MALLOC;
 
 /* Add a matching expression, returning the tag the widget assigns to that
  * expression. */
 _VTE_PUBLIC
 int vte_terminal_match_add_regex(VteTerminal *terminal,
                                  VteRegex *regex,
-                                 guint32 flags) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                 guint32 flags) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
 /* Set the cursor to be used when the pointer is over a given match. */
 _VTE_PUBLIC
 void vte_terminal_match_set_cursor_name(VteTerminal *terminal,
                                        int tag,
-                                        const char *cursor_name) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(3);
+                                        const char *cursor_name) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(3);
 _VTE_PUBLIC
 void vte_terminal_match_remove(VteTerminal *terminal,
-                               int tag) _VTE_GNUC_NONNULL(1);
+                               int tag) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-void vte_terminal_match_remove_all(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+void vte_terminal_match_remove_all(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Check if a given cell on the screen contains part of a matched string.  If
  * it does, return the string, and store the match tag in the optional tag
@@ -418,82 +418,82 @@ void vte_terminal_match_remove_all(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 char *vte_terminal_match_check_event(VteTerminal *terminal,
                                      GdkEvent *event,
-                                     int *tag) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) G_GNUC_MALLOC;
+                                     int *tag) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) 
G_GNUC_MALLOC;
 _VTE_PUBLIC
 char **vte_terminal_event_check_regex_array(VteTerminal *terminal,
                                             GdkEvent *event,
                                             VteRegex **regexes,
                                             gsize n_regexes,
                                             guint32 match_flags,
-                                            gsize *n_matches) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2) 
G_GNUC_MALLOC;
+                                            gsize *n_matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2) G_GNUC_MALLOC;
 _VTE_PUBLIC
 gboolean vte_terminal_event_check_regex_simple(VteTerminal *terminal,
                                                GdkEvent *event,
                                                VteRegex **regexes,
                                                gsize n_regexes,
                                                guint32 match_flags,
-                                               char **matches) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                               char **matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 _VTE_PUBLIC
 void      vte_terminal_search_set_regex      (VteTerminal *terminal,
                                               VteRegex    *regex,
-                                              guint32      flags) _VTE_GNUC_NONNULL(1);
+                                              guint32      flags) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-VteRegex *vte_terminal_search_get_regex      (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+VteRegex *vte_terminal_search_get_regex      (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void      vte_terminal_search_set_wrap_around (VteTerminal *terminal,
-                                              gboolean     wrap_around) _VTE_GNUC_NONNULL(1);
+                                              gboolean     wrap_around) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean  vte_terminal_search_get_wrap_around (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean  vte_terminal_search_get_wrap_around (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean  vte_terminal_search_find_previous   (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean  vte_terminal_search_find_previous   (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean  vte_terminal_search_find_next       (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean  vte_terminal_search_find_next       (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 
 /* CJK compatibility setting */
 _VTE_PUBLIC
 void vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal,
-                                          int width) _VTE_GNUC_NONNULL(1);
+                                          int width) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-int vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+int vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 _VTE_PUBLIC
 void vte_terminal_set_pty(VteTerminal *terminal,
-                          VtePty *pty) _VTE_GNUC_NONNULL(1);
+                          VtePty *pty) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-VtePty *vte_terminal_get_pty(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+VtePty *vte_terminal_get_pty(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* Accessors for bindings. */
 _VTE_PUBLIC
-glong vte_terminal_get_char_width(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+glong vte_terminal_get_char_width(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-glong vte_terminal_get_char_height(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+glong vte_terminal_get_char_height(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-glong vte_terminal_get_row_count(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+glong vte_terminal_get_row_count(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-glong vte_terminal_get_column_count(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+glong vte_terminal_get_column_count(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-const char *vte_terminal_get_window_title(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_window_title(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-const char *vte_terminal_get_current_directory_uri(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_current_directory_uri(VteTerminal *terminal) _VTE_CXX_NOEXCEPT 
_VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-const char *vte_terminal_get_current_file_uri(VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+const char *vte_terminal_get_current_file_uri(VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* misc */
 _VTE_PUBLIC
 void vte_terminal_set_input_enabled (VteTerminal *terminal,
-                                     gboolean enabled) _VTE_GNUC_NONNULL(1);
+                                     gboolean enabled) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
-gboolean vte_terminal_get_input_enabled (VteTerminal *terminal) _VTE_GNUC_NONNULL(1);
+gboolean vte_terminal_get_input_enabled (VteTerminal *terminal) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 
 /* rarely useful functions */
 _VTE_PUBLIC
 void vte_terminal_set_clear_background(VteTerminal* terminal,
-                                       gboolean setting) _VTE_GNUC_NONNULL(1);
+                                       gboolean setting) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
 _VTE_PUBLIC
 void vte_terminal_get_color_background_for_draw(VteTerminal* terminal,
-                                                GdkRGBA* color) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                                GdkRGBA* color) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 /* Writing contents out */
 _VTE_PUBLIC
@@ -501,7 +501,7 @@ gboolean vte_terminal_write_contents_sync (VteTerminal *terminal,
                                            GOutputStream *stream,
                                            VteWriteFlags flags,
                                            GCancellable *cancellable,
-                                           GError **error) _VTE_GNUC_NONNULL(1) _VTE_GNUC_NONNULL(2);
+                                           GError **error) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) 
_VTE_GNUC_NONNULL(2);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VteTerminal, g_object_unref)
 
diff --git a/src/vte/vteversion.h.in b/src/vte/vteversion.h.in
index f558c8fe..9291666f 100644
--- a/src/vte/vteversion.h.in
+++ b/src/vte/vteversion.h.in
@@ -76,13 +76,13 @@ G_BEGIN_DECLS
    (VTE_MAJOR_VERSION == (major) && VTE_MINOR_VERSION == (minor) && VTE_MICRO_VERSION >= (micro)))
 
 _VTE_PUBLIC
-guint vte_get_major_version (void) G_GNUC_CONST;
+guint vte_get_major_version (void) _VTE_CXX_NOEXCEPT G_GNUC_CONST;
 
 _VTE_PUBLIC
-guint vte_get_minor_version (void) G_GNUC_CONST;
+guint vte_get_minor_version (void) _VTE_CXX_NOEXCEPT G_GNUC_CONST;
 
 _VTE_PUBLIC
-guint vte_get_micro_version (void) G_GNUC_CONST;
+guint vte_get_micro_version (void) _VTE_CXX_NOEXCEPT G_GNUC_CONST;
 
 G_END_DECLS
 
diff --git a/src/vteaccess.cc b/src/vteaccess.cc
index 1851e077..336c3ccb 100644
--- a/src/vteaccess.cc
+++ b/src/vteaccess.cc
@@ -283,9 +283,12 @@ vte_terminal_accessible_update_private_data_if_needed(VteTerminalAccessible *acc
                priv->snapshot_linebreaks = g_array_new(FALSE, FALSE, sizeof(int));
 
                /* Get a new view of the uber-label. */
-               priv->snapshot_text = impl->get_text_displayed_a11y(true /* wrap */,
-                                                                             priv->snapshot_attributes);
-
+                try {
+                        priv->snapshot_text = impl->get_text_displayed_a11y(true /* wrap */,
+                                                                            priv->snapshot_attributes);
+                } catch (...) {
+                        priv->snapshot_text = g_string_new("");
+                }
                /* Get the offsets to the beginnings of each character. */
                i = 0;
                next = priv->snapshot_text->str;
@@ -712,7 +715,10 @@ vte_terminal_accessible_initialize (AtkObject *obj, gpointer data)
        ATK_OBJECT_CLASS (_vte_terminal_accessible_parent_class)->initialize (obj, data);
 
         auto impl = IMPL(terminal);
-        impl->subscribe_accessible_events();
+        try {
+                impl->subscribe_accessible_events();
+        } catch (...) {
+        }
 
        g_signal_connect(terminal, "text-inserted",
                         G_CALLBACK(vte_terminal_accessible_text_modified),
@@ -1419,15 +1425,18 @@ vte_terminal_accessible_get_selection(AtkText *text, gint selection_number,
                return NULL;
        }
 
-        auto impl = IMPL_FROM_WIDGET(widget);
+        try {
+                auto impl = IMPL_FROM_WIDGET(widget);
+                if (impl->m_selection_resolved.empty() || impl->m_selection[VTE_SELECTION_PRIMARY] == 
nullptr)
+                        return nullptr;
 
-        if (impl->m_selection_resolved.empty() || impl->m_selection[VTE_SELECTION_PRIMARY] == nullptr)
-               return NULL;
-
-        *start_offset = offset_from_xy (priv, impl->m_selection_resolved.start_column(), 
impl->m_selection_resolved.start_row());
-        *end_offset = offset_from_xy (priv, impl->m_selection_resolved.end_column(), 
impl->m_selection_resolved.end_row());
+                *start_offset = offset_from_xy (priv, impl->m_selection_resolved.start_column(), 
impl->m_selection_resolved.start_row());
+                *end_offset = offset_from_xy (priv, impl->m_selection_resolved.end_column(), 
impl->m_selection_resolved.end_row());
 
-       return g_strdup(impl->m_selection[VTE_SELECTION_PRIMARY]->str);
+                return g_strdup(impl->m_selection[VTE_SELECTION_PRIMARY]->str);
+        } catch (...) {
+                return nullptr;
+        }
 }
 
 static gboolean
@@ -1472,7 +1481,10 @@ vte_terminal_accessible_remove_selection(AtkText *text,
        terminal = VTE_TERMINAL (widget);
         auto impl = IMPL_FROM_WIDGET(widget);
        if (selection_number == 0 && vte_terminal_get_has_selection (terminal)) {
-               impl->deselect_all();
+                try {
+                        impl->deselect_all();
+                } catch (...) {
+                }
                return TRUE;
        } else {
                return FALSE;
@@ -1501,7 +1513,10 @@ vte_terminal_accessible_set_selection(AtkText *text, gint selection_number,
                return FALSE;
        }
        if (vte_terminal_get_has_selection (terminal)) {
-               impl->deselect_all();
+                try {
+                        impl->deselect_all();
+                } catch (...) {
+                }
        }
 
        return vte_terminal_accessible_add_selection (text, start_offset, end_offset);
@@ -1576,17 +1591,21 @@ vte_terminal_accessible_set_size(AtkComponent *component,
 
         /* If the size is an exact multiple of the cell size, use that,
          * otherwise round down. */
-        width -= impl->m_padding.left + impl->m_padding.right;
-        height -= impl->m_padding.top + impl->m_padding.bottom;
-
-        auto columns = width / impl->m_cell_width;
-        auto rows = height / impl->m_cell_height;
-        if (columns <= 0 || rows <= 0)
-                return FALSE;
-
-       vte_terminal_set_size(terminal, columns, rows);
-       return (vte_terminal_get_row_count (terminal) == rows) &&
-              (vte_terminal_get_column_count (terminal) == columns);
+        try {
+                width -= impl->m_padding.left + impl->m_padding.right;
+                height -= impl->m_padding.top + impl->m_padding.bottom;
+
+                auto columns = width / impl->m_cell_width;
+                auto rows = height / impl->m_cell_height;
+                if (columns <= 0 || rows <= 0)
+                        return FALSE;
+
+                vte_terminal_set_size(terminal, columns, rows);
+                return (vte_terminal_get_row_count (terminal) == rows) &&
+                        (vte_terminal_get_column_count (terminal) == columns);
+        } catch (...) {
+                return false;
+        }
 }
 
 static AtkObject *
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index db334d62..8452b1e2 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -32,6 +32,7 @@
 #include "config.h"
 
 #include <new> /* placement new */
+#include <exception>
 
 #include <pwd.h>
 
@@ -49,6 +50,7 @@
 
 #include "debug.h"
 #include "glib-glue.hh"
+#include "gobject-glue.hh"
 #include "marshal.h"
 #include "reaper.hh"
 #include "vtedefines.hh"
@@ -119,7 +121,7 @@ GTimer *process_timer;
 uint64_t g_test_flags = 0;
 
 static bool
-valid_color(GdkRGBA const* color)
+valid_color(GdkRGBA const* color) noexcept
 {
         return color->red >= 0. && color->red <= 1. &&
                color->green >= 0. && color->green <= 1. &&
@@ -129,50 +131,81 @@ valid_color(GdkRGBA const* color)
 
 static void
 vte_terminal_set_hadjustment(VteTerminal *terminal,
-                             GtkAdjustment *adjustment)
+                             GtkAdjustment *adjustment) noexcept
+try
 {
         g_return_if_fail(adjustment == nullptr || GTK_IS_ADJUSTMENT(adjustment));
         WIDGET(terminal)->set_hadjustment(vte::glib::make_ref_sink(adjustment));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_set_vadjustment(VteTerminal *terminal,
-                             GtkAdjustment *adjustment)
+                             GtkAdjustment *adjustment) noexcept
+try
 {
         g_return_if_fail(adjustment == nullptr || GTK_IS_ADJUSTMENT(adjustment));
         WIDGET(terminal)->set_vadjustment(vte::glib::make_ref_sink(adjustment));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_set_hscroll_policy(VteTerminal *terminal,
-                                GtkScrollablePolicy policy)
+                                GtkScrollablePolicy policy) noexcept
+try
 {
         WIDGET(terminal)->set_hscroll_policy(policy);
         gtk_widget_queue_resize_no_redraw (GTK_WIDGET (terminal));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_set_vscroll_policy(VteTerminal *terminal,
-                                GtkScrollablePolicy policy)
+                                GtkScrollablePolicy policy) noexcept
+try
 {
         WIDGET(terminal)->set_vscroll_policy(policy);
         gtk_widget_queue_resize_no_redraw (GTK_WIDGET (terminal));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_real_copy_clipboard(VteTerminal *terminal)
+vte_terminal_real_copy_clipboard(VteTerminal *terminal) noexcept
+try
 {
        WIDGET(terminal)->copy(VTE_SELECTION_CLIPBOARD, VTE_FORMAT_TEXT);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_real_paste_clipboard(VteTerminal *terminal)
+vte_terminal_real_paste_clipboard(VteTerminal *terminal) noexcept
+try
 {
        WIDGET(terminal)->paste(GDK_SELECTION_CLIPBOARD);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_style_updated (GtkWidget *widget)
+vte_terminal_style_updated (GtkWidget *widget) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
 
@@ -180,9 +213,15 @@ vte_terminal_style_updated (GtkWidget *widget)
 
         WIDGET(terminal)->style_updated();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static gboolean
-vte_terminal_key_press(GtkWidget *widget, GdkEventKey *event)
+vte_terminal_key_press(GtkWidget *widget,
+                       GdkEventKey *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
 
@@ -204,61 +243,117 @@ vte_terminal_key_press(GtkWidget *widget, GdkEventKey *event)
 
         return WIDGET(terminal)->key_press(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_key_release(GtkWidget *widget, GdkEventKey *event)
+vte_terminal_key_release(GtkWidget *widget,
+                         GdkEventKey *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         return WIDGET(terminal)->key_release(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_motion_notify(GtkWidget *widget, GdkEventMotion *event)
+vte_terminal_motion_notify(GtkWidget *widget,
+                           GdkEventMotion *event) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL(widget);
         return WIDGET(terminal)->motion_notify(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_button_press(GtkWidget *widget, GdkEventButton *event)
+vte_terminal_button_press(GtkWidget *widget,
+                          GdkEventButton *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         return WIDGET(terminal)->button_press(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_button_release(GtkWidget *widget, GdkEventButton *event)
+vte_terminal_button_release(GtkWidget *widget,
+                            GdkEventButton *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         return WIDGET(terminal)->button_release(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_scroll(GtkWidget *widget, GdkEventScroll *event)
+vte_terminal_scroll(GtkWidget *widget,
+                    GdkEventScroll *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->scroll(event);
         return TRUE;
 }
+catch (...)
+{
+        vte::log_exception();
+        return true;
+}
 
 static gboolean
-vte_terminal_focus_in(GtkWidget *widget, GdkEventFocus *event)
+vte_terminal_focus_in(GtkWidget *widget,
+                      GdkEventFocus *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->focus_in(event);
         return FALSE;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static gboolean
-vte_terminal_focus_out(GtkWidget *widget, GdkEventFocus *event)
+vte_terminal_focus_out(GtkWidget *widget,
+                       GdkEventFocus *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->focus_out(event);
         return FALSE;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static gboolean
-vte_terminal_enter(GtkWidget *widget, GdkEventCrossing *event)
+vte_terminal_enter(GtkWidget *widget,
+                   GdkEventCrossing *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         gboolean ret = FALSE;
@@ -271,9 +366,16 @@ vte_terminal_enter(GtkWidget *widget, GdkEventCrossing *event)
 
         return ret;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static gboolean
-vte_terminal_leave(GtkWidget *widget, GdkEventCrossing *event)
+vte_terminal_leave(GtkWidget *widget,
+                   GdkEventCrossing *event) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
        gboolean ret = FALSE;
@@ -286,43 +388,71 @@ vte_terminal_leave(GtkWidget *widget, GdkEventCrossing *event)
 
         return ret;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static void
 vte_terminal_get_preferred_width(GtkWidget *widget,
                                 int       *minimum_width,
-                                int       *natural_width)
+                                int       *natural_width) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->get_preferred_width(minimum_width, natural_width);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_get_preferred_height(GtkWidget *widget,
                                  int       *minimum_height,
-                                 int       *natural_height)
+                                 int       *natural_height) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->get_preferred_height(minimum_height, natural_height);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+vte_terminal_size_allocate(GtkWidget *widget,
+                           GtkAllocation *allocation) noexcept
+try
 {
        VteTerminal *terminal = VTE_TERMINAL(widget);
         WIDGET(terminal)->size_allocate(allocation);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static gboolean
 vte_terminal_draw(GtkWidget *widget,
-                  cairo_t *cr)
+                  cairo_t *cr) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL (widget);
         WIDGET(terminal)->draw(cr);
         return FALSE;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static void
-vte_terminal_realize(GtkWidget *widget)
+vte_terminal_realize(GtkWidget *widget) noexcept
+try
 {
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_realize()\n");
 
@@ -331,20 +461,29 @@ vte_terminal_realize(GtkWidget *widget)
         VteTerminal *terminal= VTE_TERMINAL(widget);
         WIDGET(terminal)->realize();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_unrealize(GtkWidget *widget)
+vte_terminal_unrealize(GtkWidget *widget) noexcept
 {
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_unrealize()\n");
 
-        VteTerminal *terminal = VTE_TERMINAL (widget);
-        WIDGET(terminal)->unrealize();
+        try {
+                VteTerminal *terminal = VTE_TERMINAL (widget);
+                WIDGET(terminal)->unrealize();
+        } catch (...) {
+                vte::log_exception();
+        }
 
         GTK_WIDGET_CLASS(vte_terminal_parent_class)->unrealize(widget);
 }
 
 static void
-vte_terminal_map(GtkWidget *widget)
+vte_terminal_map(GtkWidget *widget) noexcept
+try
 {
         _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_map()\n");
 
@@ -353,21 +492,30 @@ vte_terminal_map(GtkWidget *widget)
 
         WIDGET(terminal)->map();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_unmap(GtkWidget *widget)
+vte_terminal_unmap(GtkWidget *widget) noexcept
 {
         _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_unmap()\n");
 
-        VteTerminal *terminal = VTE_TERMINAL(widget);
-        WIDGET(terminal)->unmap();
+        try {
+                VteTerminal *terminal = VTE_TERMINAL(widget);
+                WIDGET(terminal)->unmap();
+        } catch (...) {
+                vte::log_exception();
+        }
 
         GTK_WIDGET_CLASS(vte_terminal_parent_class)->unmap(widget);
 }
 
 static void
 vte_terminal_screen_changed (GtkWidget *widget,
-                             GdkScreen *previous_screen)
+                             GdkScreen *previous_screen) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL (widget);
 
@@ -377,9 +525,14 @@ vte_terminal_screen_changed (GtkWidget *widget,
 
         WIDGET(terminal)->screen_changed(previous_screen);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
-vte_terminal_constructed (GObject *object)
+vte_terminal_constructed (GObject *object) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL (object);
 
@@ -387,9 +540,14 @@ vte_terminal_constructed (GObject *object)
 
         WIDGET(terminal)->constructed();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_init(VteTerminal *terminal)
+try
 {
         void *place;
        GtkStyleContext *context;
@@ -401,32 +559,48 @@ vte_terminal_init(VteTerminal *terminal)
                                         VTE_TERMINAL_GET_CLASS (terminal)->priv->style_provider,
                                         GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
+        gtk_widget_set_has_window(&terminal->widget, FALSE);
+
        /* Initialize private data. NOTE: place is zeroed */
        place = vte_terminal_get_instance_private(terminal);
         new (place) vte::platform::Widget(terminal);
+}
+catch (...)
+{
+        vte::log_exception();
 
-        gtk_widget_set_has_window(&terminal->widget, FALSE);
+        // There's not really anything we can do after the
+        // construction of Widget failed... we'll crash soon anyway.
+        g_assert_not_reached();
 }
 
 static void
-vte_terminal_dispose(GObject *object)
+vte_terminal_dispose(GObject *object) noexcept
 {
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_dispose()\n");
 
-       VteTerminal *terminal = VTE_TERMINAL (object);
-        WIDGET(terminal)->dispose();
+        try {
+                VteTerminal *terminal = VTE_TERMINAL (object);
+                WIDGET(terminal)->dispose();
+        } catch (...) {
+                vte::log_exception();
+        }
 
        /* Call the inherited dispose() method. */
        G_OBJECT_CLASS(vte_terminal_parent_class)->dispose(object);
 }
 
 static void
-vte_terminal_finalize(GObject *object)
+vte_terminal_finalize(GObject *object) noexcept
 {
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_finalize()\n");
 
-       VteTerminal *terminal = VTE_TERMINAL (object);
-        WIDGET(terminal)->~Widget();
+        try {
+                VteTerminal *terminal = VTE_TERMINAL (object);
+                WIDGET(terminal)->~Widget();
+        } catch (...) {
+                vte::log_exception();
+        }
 
        /* Call the inherited finalize() method. */
        G_OBJECT_CLASS(vte_terminal_parent_class)->finalize(object);
@@ -436,7 +610,8 @@ static void
 vte_terminal_get_property (GObject *object,
                            guint prop_id,
                            GValue *value,
-                           GParamSpec *pspec)
+                           GParamSpec *pspec) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL (object);
         auto widget = WIDGET(terminal);
@@ -552,12 +727,17 @@ vte_terminal_get_property (GObject *object,
                        return;
                 }
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_set_property (GObject *object,
                            guint prop_id,
                            const GValue *value,
-                           GParamSpec *pspec)
+                           GParamSpec *pspec) noexcept
+try
 {
         VteTerminal *terminal = VTE_TERMINAL (object);
 
@@ -665,6 +845,10 @@ vte_terminal_set_property (GObject *object,
                        return;
                 }
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_terminal_class_init(VteTerminalClass *klass)
@@ -1839,7 +2023,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
  * Since: 0.40
  */
 const char *
-vte_get_features (void)
+vte_get_features (void) noexcept
 {
         return
 #ifdef WITH_FRIBIDI
@@ -1883,7 +2067,7 @@ vte_get_features (void)
  * Since: 0.40
  */
 guint
-vte_get_major_version (void)
+vte_get_major_version (void) noexcept
 {
         return VTE_MAJOR_VERSION;
 }
@@ -1901,7 +2085,7 @@ vte_get_major_version (void)
  * Since: 0.40
  */
 guint
-vte_get_minor_version (void)
+vte_get_minor_version (void) noexcept
 {
         return VTE_MINOR_VERSION;
 }
@@ -1919,7 +2103,7 @@ vte_get_minor_version (void)
  * Since: 0.40
  */
 guint
-vte_get_micro_version (void)
+vte_get_micro_version (void) noexcept
 {
         return VTE_MICRO_VERSION;
 }
@@ -1934,7 +2118,7 @@ vte_get_micro_version (void)
  *   user's shell, or %NULL
  */
 char *
-vte_get_user_shell (void)
+vte_get_user_shell (void) noexcept
 {
        struct passwd *pwd;
 
@@ -1955,7 +2139,7 @@ vte_get_user_shell (void)
  * Since: 0.54
  */
 void
-vte_set_test_flags(guint64 flags)
+vte_set_test_flags(guint64 flags) noexcept
 {
 #ifdef VTE_DEBUG
         g_test_flags = flags;
@@ -1979,7 +2163,8 @@ vte_set_test_flags(guint64 flags)
  * Deprecated: 0.60
  */
 char **
-vte_get_encodings(gboolean include_aliases)
+vte_get_encodings(gboolean include_aliases) noexcept
+try
 {
 #ifdef WITH_ICU
         return vte::base::get_icu_charsets(include_aliases != FALSE);
@@ -1988,6 +2173,13 @@ vte_get_encodings(gboolean include_aliases)
         return g_strdupv(empty);
 #endif
 }
+catch (...)
+{
+        vte::log_exception();
+
+        char *empty[] = { nullptr };
+        return g_strdupv(empty);
+}
 
 /**
  * vte_get_encoding_supported:
@@ -2006,7 +2198,8 @@ vte_get_encodings(gboolean include_aliases)
  * Deprecated: 0.60
  */
 gboolean
-vte_get_encoding_supported(const char *encoding)
+vte_get_encoding_supported(const char *encoding) noexcept
+try
 {
         g_return_val_if_fail(encoding != nullptr, false);
 
@@ -2016,6 +2209,11 @@ vte_get_encoding_supported(const char *encoding)
         return false;
 #endif
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /* VteTerminal public API */
 
@@ -2027,7 +2225,7 @@ vte_get_encoding_supported(const char *encoding)
  * Returns: (transfer none) (type Vte.Terminal): a new #VteTerminal object
  */
 GtkWidget *
-vte_terminal_new(void)
+vte_terminal_new(void) noexcept
 {
        return (GtkWidget *)g_object_new(VTE_TYPE_TERMINAL, nullptr);
 }
@@ -2043,13 +2241,17 @@ vte_terminal_new(void)
  *   instead.
  */
 void
-vte_terminal_copy_clipboard(VteTerminal *terminal)
+vte_terminal_copy_clipboard(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         IMPL(terminal)->emit_copy_clipboard();
 }
-
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_copy_clipboard_format:
@@ -2070,13 +2272,18 @@ vte_terminal_copy_clipboard(VteTerminal *terminal)
  */
 void
 vte_terminal_copy_clipboard_format(VteTerminal *terminal,
-                                   VteFormat format)
+                                   VteFormat format) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(format == VTE_FORMAT_TEXT || format == VTE_FORMAT_HTML);
 
         WIDGET(terminal)->copy(VTE_SELECTION_CLIPBOARD, format);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_copy_primary:
@@ -2086,12 +2293,17 @@ vte_terminal_copy_clipboard_format(VteTerminal *terminal,
  * selection.
  */
 void
-vte_terminal_copy_primary(VteTerminal *terminal)
+vte_terminal_copy_primary(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
        _vte_debug_print(VTE_DEBUG_SELECTION, "Copying to PRIMARY.\n");
        WIDGET(terminal)->copy(VTE_SELECTION_PRIMARY, VTE_FORMAT_TEXT);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_paste_clipboard:
@@ -2102,12 +2314,17 @@ vte_terminal_copy_primary(VteTerminal *terminal)
  * user presses Shift+Insert.
  */
 void
-vte_terminal_paste_clipboard(VteTerminal *terminal)
+vte_terminal_paste_clipboard(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         IMPL(terminal)->emit_paste_clipboard();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_paste_primary:
@@ -2119,12 +2336,17 @@ vte_terminal_paste_clipboard(VteTerminal *terminal)
  * mouse button.
  */
 void
-vte_terminal_paste_primary(VteTerminal *terminal)
+vte_terminal_paste_primary(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
        _vte_debug_print(VTE_DEBUG_SELECTION, "Pasting PRIMARY.\n");
        WIDGET(terminal)->paste(GDK_SELECTION_PRIMARY);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_match_add_gregex:
@@ -2141,7 +2363,7 @@ vte_terminal_paste_primary(VteTerminal *terminal)
 int
 vte_terminal_match_add_gregex(VteTerminal *terminal,
                               GRegex *gregex,
-                              GRegexMatchFlags gflags)
+                              GRegexMatchFlags gflags) noexcept
 {
         return -1;
 }
@@ -2165,7 +2387,8 @@ vte_terminal_match_add_gregex(VteTerminal *terminal,
 int
 vte_terminal_match_add_regex(VteTerminal *terminal,
                              VteRegex    *regex,
-                             guint32      flags)
+                             guint32      flags) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        g_return_val_if_fail(regex != NULL, -1);
@@ -2178,6 +2401,11 @@ vte_terminal_match_add_regex(VteTerminal *terminal,
                                      VTE_DEFAULT_CURSOR,
                                      impl->regex_match_next_tag()).tag();
 }
+catch (...)
+{
+        vte::log_exception();
+        return -1;
+}
 
 /**
  * vte_terminal_match_check:
@@ -2204,12 +2432,17 @@ char *
 vte_terminal_match_check(VteTerminal *terminal,
                          long column,
                          long row,
-                        int *tag)
+                        int *tag) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
         return WIDGET(terminal)->regex_match_check(column, row, tag);
 }
-
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_match_check_event:
@@ -2232,11 +2465,17 @@ vte_terminal_match_check(VteTerminal *terminal,
 char *
 vte_terminal_match_check_event(VteTerminal *terminal,
                                GdkEvent *event,
-                               int *tag)
+                               int *tag) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
         return WIDGET(terminal)->regex_match_check(event, tag);
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_hyperlink_check_event:
@@ -2257,11 +2496,17 @@ vte_terminal_match_check_event(VteTerminal *terminal,
  */
 char *
 vte_terminal_hyperlink_check_event(VteTerminal *terminal,
-                                   GdkEvent *event)
+                                   GdkEvent *event) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
         return WIDGET(terminal)->hyperlink_check(event);
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_event_check_regex_array: (rename-to vte_terminal_event_check_regex_simple)
@@ -2290,7 +2535,8 @@ vte_terminal_event_check_regex_array(VteTerminal *terminal,
                                      VteRegex **regexes,
                                      gsize n_regexes,
                                      guint32 match_flags,
-                                     gsize *n_matches)
+                                     gsize *n_matches) noexcept
+try
 {
         if (n_matches)
                 *n_matches = n_regexes;
@@ -2309,6 +2555,11 @@ vte_terminal_event_check_regex_array(VteTerminal *terminal,
 
         return matches.release();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_event_check_regex_simple: (skip)
@@ -2337,7 +2588,8 @@ vte_terminal_event_check_regex_simple(VteTerminal *terminal,
                                       VteRegex **regexes,
                                       gsize n_regexes,
                                       guint32 match_flags,
-                                      char **matches)
+                                      char **matches) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
         g_return_val_if_fail(event != NULL, FALSE);
@@ -2354,6 +2606,11 @@ vte_terminal_event_check_regex_simple(VteTerminal *terminal,
                                                          match_flags,
                                                          matches);
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_event_check_gregex_simple:
@@ -2377,7 +2634,7 @@ vte_terminal_event_check_gregex_simple(VteTerminal *terminal,
                                        GRegex **regexes,
                                        gsize n_regexes,
                                        GRegexMatchFlags match_flags,
-                                       char **matches)
+                                       char **matches) noexcept
 {
         return FALSE;
 }
@@ -2397,13 +2654,18 @@ vte_terminal_event_check_gregex_simple(VteTerminal *terminal,
 void
 vte_terminal_match_set_cursor(VteTerminal *terminal,
                               int tag,
-                              GdkCursor *cursor)
+                              GdkCursor *cursor) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(tag >= 0);
         if (auto rem = IMPL(terminal)->regex_match_get(tag))
                 rem->set_cursor(vte::glib::make_ref<GdkCursor>(cursor));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_match_set_cursor_type:
@@ -2419,13 +2681,18 @@ vte_terminal_match_set_cursor(VteTerminal *terminal,
 void
 vte_terminal_match_set_cursor_type(VteTerminal *terminal,
                                   int tag,
-                                   GdkCursorType cursor_type)
+                                   GdkCursorType cursor_type) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(tag >= 0);
         if (auto rem = IMPL(terminal)->regex_match_get(tag))
                 rem->set_cursor(cursor_type);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_match_set_cursor_name:
@@ -2439,13 +2706,18 @@ vte_terminal_match_set_cursor_type(VteTerminal *terminal,
 void
 vte_terminal_match_set_cursor_name(VteTerminal *terminal,
                                   int tag,
-                                   const char *cursor_name)
+                                   const char *cursor_name) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(tag >= 0);
         if (auto rem = IMPL(terminal)->regex_match_get(tag))
                 rem->set_cursor(cursor_name);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_match_remove:
@@ -2457,11 +2729,17 @@ vte_terminal_match_set_cursor_name(VteTerminal *terminal,
  * moves the mouse cursor over matching text.
  */
 void
-vte_terminal_match_remove(VteTerminal *terminal, int tag)
+vte_terminal_match_remove(VteTerminal *terminal,
+                          int tag) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         IMPL(terminal)->regex_match_remove(tag);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_match_remove_all:
@@ -2471,11 +2749,16 @@ vte_terminal_match_remove(VteTerminal *terminal, int tag)
  * when the user moves the mouse cursor.
  */
 void
-vte_terminal_match_remove_all(VteTerminal *terminal)
+vte_terminal_match_remove_all(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         IMPL(terminal)->regex_match_remove_all();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_search_find_previous:
@@ -2487,11 +2770,17 @@ vte_terminal_match_remove_all(VteTerminal *terminal)
  * Returns: %TRUE if a match was found
  */
 gboolean
-vte_terminal_search_find_previous (VteTerminal *terminal)
+vte_terminal_search_find_previous (VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->search_find(true);
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_search_find_next:
@@ -2503,11 +2792,17 @@ vte_terminal_search_find_previous (VteTerminal *terminal)
  * Returns: %TRUE if a match was found
  */
 gboolean
-vte_terminal_search_find_next (VteTerminal *terminal)
+vte_terminal_search_find_next (VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->search_find(false);
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_search_set_regex:
@@ -2524,7 +2819,8 @@ vte_terminal_search_find_next (VteTerminal *terminal)
 void
 vte_terminal_search_set_regex (VteTerminal *terminal,
                                VteRegex    *regex,
-                               guint32      flags)
+                               guint32      flags) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(regex == nullptr || _vte_regex_has_purpose(regex, 
vte::base::Regex::Purpose::eSearch));
@@ -2532,6 +2828,10 @@ vte_terminal_search_set_regex (VteTerminal *terminal,
 
         IMPL(terminal)->search_set_regex(vte::base::make_ref(regex_from_wrapper(regex)), flags);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_search_get_regex:
@@ -2542,12 +2842,18 @@ vte_terminal_search_set_regex (VteTerminal *terminal,
  * Since: 0.46
  */
 VteRegex *
-vte_terminal_search_get_regex(VteTerminal *terminal)
+vte_terminal_search_get_regex(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
 
         return wrapper_from_regex(IMPL(terminal)->search_regex());
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_search_set_gregex:
@@ -2562,7 +2868,7 @@ vte_terminal_search_get_regex(VteTerminal *terminal)
 void
 vte_terminal_search_set_gregex (VteTerminal *terminal,
                                GRegex      *gregex,
-                                GRegexMatchFlags gflags)
+                                GRegexMatchFlags gflags) noexcept
 {
 }
 
@@ -2575,11 +2881,11 @@ vte_terminal_search_set_gregex (VteTerminal *terminal,
  * Deprecated: 0.46: use vte_terminal_search_get_regex() instead.
  */
 GRegex *
-vte_terminal_search_get_gregex (VteTerminal *terminal)
+vte_terminal_search_get_gregex (VteTerminal *terminal) noexcept
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
 
-        return NULL;
+        return nullptr;
 }
 
 /**
@@ -2592,12 +2898,17 @@ vte_terminal_search_get_gregex (VteTerminal *terminal)
  */
 void
 vte_terminal_search_set_wrap_around (VteTerminal *terminal,
-                                    gboolean     wrap_around)
+                                    gboolean     wrap_around) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         IMPL(terminal)->search_set_wrap_around(wrap_around != FALSE);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_search_get_wrap_around:
@@ -2606,13 +2917,17 @@ vte_terminal_search_set_wrap_around (VteTerminal *terminal,
  * Returns: whether searching will wrap around
  */
 gboolean
-vte_terminal_search_get_wrap_around (VteTerminal *terminal)
+vte_terminal_search_get_wrap_around (VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
-
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_search_wrap_around;
 }
-
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_select_all:
@@ -2621,12 +2936,17 @@ vte_terminal_search_get_wrap_around (VteTerminal *terminal)
  * Selects all text within the terminal (including the scrollback buffer).
  */
 void
-vte_terminal_select_all (VteTerminal *terminal)
+vte_terminal_select_all (VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail (VTE_IS_TERMINAL (terminal));
 
         IMPL(terminal)->select_all();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_unselect_all:
@@ -2635,12 +2955,17 @@ vte_terminal_select_all (VteTerminal *terminal)
  * Clears the current selection.
  */
 void
-vte_terminal_unselect_all(VteTerminal *terminal)
+vte_terminal_unselect_all(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail (VTE_IS_TERMINAL (terminal));
 
         IMPL(terminal)->deselect_all();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_cursor_position:
@@ -2656,7 +2981,8 @@ vte_terminal_unselect_all(VteTerminal *terminal)
 void
 vte_terminal_get_cursor_position(VteTerminal *terminal,
                                 long *column,
-                                 long *row)
+                                 long *row) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
@@ -2668,6 +2994,10 @@ vte_terminal_get_cursor_position(VteTerminal *terminal,
                 *row = impl->m_screen->cursor.row;
        }
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_pty_new_sync:
@@ -2688,17 +3018,23 @@ VtePty *
 vte_terminal_pty_new_sync(VteTerminal *terminal,
                           VtePtyFlags flags,
                           GCancellable *cancellable,
-                          GError **error)
+                          GError **error) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
 
-        VtePty *pty = vte_pty_new_sync(flags, cancellable, error);
-        if (pty == nullptr)
+        auto pty = vte::glib::take_ref(vte_pty_new_sync(flags, cancellable, error));
+        if (!pty)
                 return nullptr;
 
-        vte_pty_set_size(pty, IMPL(terminal)->m_row_count, IMPL(terminal)->m_column_count, NULL);
+        vte_pty_set_size(pty.get(), IMPL(terminal)->m_row_count, IMPL(terminal)->m_column_count, NULL);
 
-        return pty;
+        return pty.release();
+}
+catch (...)
+{
+        vte::glib::set_error_from_exception(error);
+        return nullptr;
 }
 
 /**
@@ -2722,7 +3058,8 @@ vte_terminal_pty_new_sync(VteTerminal *terminal,
  */
 void
 vte_terminal_watch_child (VteTerminal *terminal,
-                          GPid child_pid)
+                          GPid child_pid) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(child_pid != -1);
@@ -2731,6 +3068,10 @@ vte_terminal_watch_child (VteTerminal *terminal,
 
         IMPL(terminal)->watch_child(child_pid);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_spawn_sync:
@@ -2787,7 +3128,8 @@ vte_terminal_spawn_sync(VteTerminal *terminal,
                         gpointer child_setup_data,
                         GPid *child_pid /* out */,
                         GCancellable *cancellable,
-                        GError **error)
+                        GError **error) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
         g_return_val_if_fail(argv != NULL, FALSE);
@@ -2822,6 +3164,10 @@ vte_terminal_spawn_sync(VteTerminal *terminal,
 
         return true;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 typedef struct {
         GWeakRef wref;
@@ -2832,7 +3178,7 @@ typedef struct {
 static gpointer
 spawn_async_callback_data_new(VteTerminal *terminal,
                               VteTerminalSpawnAsyncCallback callback,
-                              gpointer user_data)
+                              gpointer user_data) noexcept
 {
         SpawnAsyncCallbackData *data = g_new0 (SpawnAsyncCallbackData, 1);
 
@@ -2844,16 +3190,16 @@ spawn_async_callback_data_new(VteTerminal *terminal,
 }
 
 static void
-spawn_async_callback_data_free (SpawnAsyncCallbackData *data)
+spawn_async_callback_data_free(SpawnAsyncCallbackData* data) noexcept
 {
         g_weak_ref_clear(&data->wref);
         g_free(data);
 }
 
 static void
-spawn_async_cb (GObject *source,
-                GAsyncResult *result,
-                gpointer user_data)
+spawn_async_cb(GObject *source,
+               GAsyncResult *result,
+               gpointer user_data) noexcept
 {
         SpawnAsyncCallbackData *data = reinterpret_cast<SpawnAsyncCallbackData*>(user_data);
         VtePty *pty = VTE_PTY(source);
@@ -2879,8 +3225,13 @@ spawn_async_cb (GObject *source,
                 }
         }
 
-        if (data->callback)
-                data->callback(terminal.get(), pid, error, data->user_data);
+        if (data->callback) {
+                try {
+                        data->callback(terminal.get(), pid, error, data->user_data);
+                } catch (...) {
+                        vte::log_exception();
+                }
+        }
 
         if (!terminal) {
                 /* If the terminal was destroyed, we need to abort the child process, if any */
@@ -3000,7 +3351,8 @@ vte_terminal_spawn_with_fds_async(VteTerminal *terminal,
                                   int timeout,
                                   GCancellable *cancellable,
                                   VteTerminalSpawnAsyncCallback callback,
-                                  gpointer user_data)
+                                  gpointer user_data) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(cancellable == nullptr || G_IS_CANCELLABLE (cancellable));
@@ -3028,6 +3380,10 @@ vte_terminal_spawn_with_fds_async(VteTerminal *terminal,
                                      spawn_async_cb,
                                      spawn_async_callback_data_new(terminal, callback, user_data));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_spawn_async:
@@ -3068,7 +3424,7 @@ vte_terminal_spawn_async(VteTerminal *terminal,
                          int timeout,
                          GCancellable *cancellable,
                          VteTerminalSpawnAsyncCallback callback,
-                         gpointer user_data)
+                         gpointer user_data) noexcept
 {
         vte_terminal_spawn_with_fds_async(terminal, pty_flags, working_directory, argv, envv,
                                           nullptr, 0, nullptr, 0,
@@ -3089,7 +3445,8 @@ vte_terminal_spawn_async(VteTerminal *terminal,
 void
 vte_terminal_feed(VteTerminal *terminal,
                   const char *data,
-                  gssize length)
+                  gssize length) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(length == 0 || data != NULL);
@@ -3100,6 +3457,10 @@ vte_terminal_feed(VteTerminal *terminal,
         auto const len = size_t{length == -1 ? strlen(data) : size_t(length)};
         WIDGET(terminal)->feed({data, len});
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_feed_child:
@@ -3113,7 +3474,8 @@ vte_terminal_feed(VteTerminal *terminal,
 void
 vte_terminal_feed_child(VteTerminal *terminal,
                         const char *text,
-                        gssize length)
+                        gssize length) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(length == 0 || text != NULL);
@@ -3124,6 +3486,10 @@ vte_terminal_feed_child(VteTerminal *terminal,
         auto const len = size_t{length == -1 ? strlen(text) : size_t(length)};
         WIDGET(terminal)->feed_child({text, len});
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_feed_child_binary:
@@ -3139,7 +3505,8 @@ vte_terminal_feed_child(VteTerminal *terminal,
 void
 vte_terminal_feed_child_binary(VteTerminal *terminal,
                                const guint8 *data,
-                               gsize length)
+                               gsize length) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(length == 0 || data != NULL);
@@ -3149,6 +3516,10 @@ vte_terminal_feed_child_binary(VteTerminal *terminal,
 
         WIDGET(terminal)->feed_child_binary({(char*)data, length});
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * VteSelectionFunc:
@@ -3164,7 +3535,7 @@ vte_terminal_feed_child_binary(VteTerminal *terminal,
  */
 
 static void
-warn_if_callback(VteSelectionFunc func)
+warn_if_callback(VteSelectionFunc func) noexcept
 {
         if (!func)
                 return;
@@ -3200,7 +3571,8 @@ char *
 vte_terminal_get_text(VteTerminal *terminal,
                      VteSelectionFunc is_selected,
                      gpointer user_data,
-                     GArray *attributes)
+                     GArray *attributes) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
         warn_if_callback(is_selected);
@@ -3210,6 +3582,11 @@ vte_terminal_get_text(VteTerminal *terminal,
                 return nullptr;
         return (char*)g_string_free(text, FALSE);
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_get_text_include_trailing_spaces:
@@ -3235,7 +3612,7 @@ char *
 vte_terminal_get_text_include_trailing_spaces(VteTerminal *terminal,
                                              VteSelectionFunc is_selected,
                                              gpointer user_data,
-                                             GArray *attributes)
+                                             GArray *attributes) noexcept
 {
         return vte_terminal_get_text(terminal, is_selected, user_data, attributes);
 }
@@ -3272,7 +3649,8 @@ vte_terminal_get_text_range(VteTerminal *terminal,
                             long end_col,
                            VteSelectionFunc is_selected,
                            gpointer user_data,
-                           GArray *attributes)
+                           GArray *attributes) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
         warn_if_callback(is_selected);
@@ -3285,6 +3663,11 @@ vte_terminal_get_text_range(VteTerminal *terminal,
                 return nullptr;
         return (char*)g_string_free(text, FALSE);
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_reset:
@@ -3301,11 +3684,16 @@ vte_terminal_get_text_range(VteTerminal *terminal,
 void
 vte_terminal_reset(VteTerminal *terminal,
                    gboolean clear_tabstops,
-                   gboolean clear_history)
+                   gboolean clear_history) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         IMPL(terminal)->reset(clear_tabstops, clear_history, true);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_size:
@@ -3319,13 +3707,18 @@ vte_terminal_reset(VteTerminal *terminal,
 void
 vte_terminal_set_size(VteTerminal *terminal,
                       long columns,
-                      long rows)
+                      long rows) noexcept
+try
 {
         g_return_if_fail(columns >= 1);
         g_return_if_fail(rows >= 1);
 
         IMPL(terminal)->set_size(columns, rows);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_text_blink_mode:
@@ -3338,11 +3731,17 @@ vte_terminal_set_size(VteTerminal *terminal,
  * Since: 0.52
  */
 VteTextBlinkMode
-vte_terminal_get_text_blink_mode(VteTerminal *terminal)
+vte_terminal_get_text_blink_mode(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), VTE_TEXT_BLINK_ALWAYS);
         return WIDGET(terminal)->text_blink_mode();
 }
+catch (...)
+{
+        vte::log_exception();
+        return VTE_TEXT_BLINK_ALWAYS;
+}
 
 /**
  * vte_terminal_set_text_blink_mode:
@@ -3355,13 +3754,18 @@ vte_terminal_get_text_blink_mode(VteTerminal *terminal)
  */
 void
 vte_terminal_set_text_blink_mode(VteTerminal *terminal,
-                                     VteTextBlinkMode text_blink_mode)
+                                 VteTextBlinkMode text_blink_mode) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (WIDGET(terminal)->set_text_blink_mode(text_blink_mode))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_TEXT_BLINK_MODE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_allow_bold:
@@ -3375,11 +3779,17 @@ vte_terminal_set_text_blink_mode(VteTerminal *terminal,
  * Deprecated: 0.60: There's probably no reason for this feature to exist.
  */
 gboolean
-vte_terminal_get_allow_bold(VteTerminal *terminal)
+vte_terminal_get_allow_bold(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_allow_bold;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_allow_bold:
@@ -3393,13 +3803,18 @@ vte_terminal_get_allow_bold(VteTerminal *terminal)
  */
 void
 vte_terminal_set_allow_bold(VteTerminal *terminal,
-                            gboolean allow_bold)
+                            gboolean allow_bold) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_allow_bold(allow_bold != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_ALLOW_BOLD]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_allow_hyperlink:
@@ -3412,11 +3827,17 @@ vte_terminal_set_allow_bold(VteTerminal *terminal,
  * Since: 0.50
  */
 gboolean
-vte_terminal_get_allow_hyperlink(VteTerminal *terminal)
+vte_terminal_get_allow_hyperlink(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
         return IMPL(terminal)->m_allow_hyperlink;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_allow_hyperlink:
@@ -3429,13 +3850,18 @@ vte_terminal_get_allow_hyperlink(VteTerminal *terminal)
  */
 void
 vte_terminal_set_allow_hyperlink(VteTerminal *terminal,
-                                 gboolean allow_hyperlink)
+                                 gboolean allow_hyperlink) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_allow_hyperlink(allow_hyperlink != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_ALLOW_HYPERLINK]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_audible_bell:
@@ -3447,11 +3873,17 @@ vte_terminal_set_allow_hyperlink(VteTerminal *terminal,
  * Returns: %TRUE if audible bell is enabled, %FALSE if not
  */
 gboolean
-vte_terminal_get_audible_bell(VteTerminal *terminal)
+vte_terminal_get_audible_bell(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_audible_bell;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_audible_bell:
@@ -3463,13 +3895,18 @@ vte_terminal_get_audible_bell(VteTerminal *terminal)
  */
 void
 vte_terminal_set_audible_bell(VteTerminal *terminal,
-                              gboolean is_audible)
+                              gboolean is_audible) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_audible_bell(is_audible != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_AUDIBLE_BELL]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_backspace_binding:
@@ -3482,7 +3919,8 @@ vte_terminal_set_audible_bell(VteTerminal *terminal,
  */
 void
 vte_terminal_set_backspace_binding(VteTerminal *terminal,
-                                   VteEraseBinding binding)
+                                   VteEraseBinding binding) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(binding >= VTE_ERASE_AUTO && binding <= VTE_ERASE_TTY);
@@ -3490,6 +3928,10 @@ vte_terminal_set_backspace_binding(VteTerminal *terminal,
         if (WIDGET(terminal)->set_backspace_binding(binding))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_BACKSPACE_BINDING]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_bold_is_bright:
@@ -3504,11 +3946,18 @@ vte_terminal_set_backspace_binding(VteTerminal *terminal,
  * Since: 0.52
  */
 gboolean
-vte_terminal_get_bold_is_bright(VteTerminal *terminal)
+vte_terminal_get_bold_is_bright(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_bold_is_bright;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
+
 /**
  * vte_terminal_set_bold_is_bright:
  * @terminal: a #VteTerminal
@@ -3522,13 +3971,18 @@ vte_terminal_get_bold_is_bright(VteTerminal *terminal)
  */
 void
 vte_terminal_set_bold_is_bright(VteTerminal *terminal,
-                                gboolean bold_is_bright)
+                                gboolean bold_is_bright) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_bold_is_bright(bold_is_bright != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_BOLD_IS_BRIGHT]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_char_height:
@@ -3540,11 +3994,17 @@ vte_terminal_set_bold_is_bright(VteTerminal *terminal,
  * because the return value takes cell-height-scale into account.
  */
 glong
-vte_terminal_get_char_height(VteTerminal *terminal)
+vte_terminal_get_char_height(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        return IMPL(terminal)->get_cell_height();
 }
+catch (...)
+{
+        vte::log_exception();
+        return -1;
+}
 
 /**
  * vte_terminal_get_char_width:
@@ -3556,11 +4016,17 @@ vte_terminal_get_char_height(VteTerminal *terminal)
  * because the return value takes cell-width-scale into account.
  */
 glong
-vte_terminal_get_char_width(VteTerminal *terminal)
+vte_terminal_get_char_width(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        return IMPL(terminal)->get_cell_width();
 }
+catch (...)
+{
+        vte::log_exception();
+        return -1;
+}
 
 /**
  * vte_terminal_get_cjk_ambiguous_width:
@@ -3574,11 +4040,17 @@ vte_terminal_get_char_width(VteTerminal *terminal)
  * Returns: 1 if ambiguous-width characters are narrow, or 2 if they are wide
  */
 int
-vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal)
+vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 1);
         return IMPL(terminal)->m_utf8_ambiguous_width;
 }
+catch (...)
+{
+        vte::log_exception();
+        return 1;
+}
 
 /**
  * vte_terminal_set_cjk_ambiguous_width:
@@ -3591,7 +4063,8 @@ vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal)
  * itself.)
  */
 void
-vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width)
+vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(width == 1 || width == 2);
@@ -3599,6 +4072,10 @@ vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width)
         if (IMPL(terminal)->set_cjk_ambiguous_width(width))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_CJK_AMBIGUOUS_WIDTH]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_background:
@@ -3611,7 +4088,8 @@ vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width)
  */
 void
 vte_terminal_set_color_background(VteTerminal *terminal,
-                                  const GdkRGBA *background)
+                                  const GdkRGBA *background) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(background != NULL);
@@ -3621,6 +4099,10 @@ vte_terminal_set_color_background(VteTerminal *terminal,
         impl->set_color_background(vte::color::rgb(background));
         impl->set_background_alpha(background->alpha);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_bold:
@@ -3632,7 +4114,8 @@ vte_terminal_set_color_background(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_bold(VteTerminal *terminal,
-                            const GdkRGBA *bold)
+                            const GdkRGBA *bold) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(bold == nullptr || valid_color(bold));
@@ -3643,6 +4126,10 @@ vte_terminal_set_color_bold(VteTerminal *terminal,
         else
                 impl->reset_color_bold();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_cursor:
@@ -3655,7 +4142,8 @@ vte_terminal_set_color_bold(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_cursor(VteTerminal *terminal,
-                              const GdkRGBA *cursor_background)
+                              const GdkRGBA *cursor_background) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(cursor_background == nullptr || valid_color(cursor_background));
@@ -3666,6 +4154,10 @@ vte_terminal_set_color_cursor(VteTerminal *terminal,
         else
                 impl->reset_color_cursor_background();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_cursor_foreground:
@@ -3680,7 +4172,8 @@ vte_terminal_set_color_cursor(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_cursor_foreground(VteTerminal *terminal,
-                                         const GdkRGBA *cursor_foreground)
+                                         const GdkRGBA *cursor_foreground) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(cursor_foreground == nullptr || valid_color(cursor_foreground));
@@ -3691,6 +4184,10 @@ vte_terminal_set_color_cursor_foreground(VteTerminal *terminal,
         else
                 impl->reset_color_cursor_foreground();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_foreground:
@@ -3701,7 +4198,8 @@ vte_terminal_set_color_cursor_foreground(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_foreground(VteTerminal *terminal,
-                                  const GdkRGBA *foreground)
+                                  const GdkRGBA *foreground) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(foreground != nullptr);
@@ -3709,6 +4207,10 @@ vte_terminal_set_color_foreground(VteTerminal *terminal,
 
         IMPL(terminal)->set_color_foreground(vte::color::rgb(foreground));
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_highlight:
@@ -3722,7 +4224,8 @@ vte_terminal_set_color_foreground(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_highlight(VteTerminal *terminal,
-                                 const GdkRGBA *highlight_background)
+                                 const GdkRGBA *highlight_background) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(highlight_background == nullptr || valid_color(highlight_background));
@@ -3733,6 +4236,10 @@ vte_terminal_set_color_highlight(VteTerminal *terminal,
         else
                 impl->reset_color_highlight_background();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_color_highlight_foreground:
@@ -3746,7 +4253,8 @@ vte_terminal_set_color_highlight(VteTerminal *terminal,
  */
 void
 vte_terminal_set_color_highlight_foreground(VteTerminal *terminal,
-                                            const GdkRGBA *highlight_foreground)
+                                            const GdkRGBA *highlight_foreground) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(highlight_foreground == nullptr || valid_color(highlight_foreground));
@@ -3757,6 +4265,10 @@ vte_terminal_set_color_highlight_foreground(VteTerminal *terminal,
         else
                 impl->reset_color_highlight_foreground();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_colors:
@@ -3781,7 +4293,8 @@ vte_terminal_set_colors(VteTerminal *terminal,
                         const GdkRGBA *foreground,
                         const GdkRGBA *background,
                         const GdkRGBA *palette,
-                        gsize palette_size)
+                        gsize palette_size) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
        g_return_if_fail((palette_size == 0) ||
@@ -3815,6 +4328,10 @@ vte_terminal_set_colors(VteTerminal *terminal,
         impl->set_background_alpha(background ? background->alpha : 1.0);
         g_free(pal);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_default_colors:
@@ -3823,11 +4340,16 @@ vte_terminal_set_colors(VteTerminal *terminal,
  * Reset the terminal palette to reasonable compiled-in default color.
  */
 void
-vte_terminal_set_default_colors(VteTerminal *terminal)
+vte_terminal_set_default_colors(VteTerminal *terminal) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         IMPL(terminal)->set_colors_default();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_column_count:
@@ -3836,11 +4358,17 @@ vte_terminal_set_default_colors(VteTerminal *terminal)
  * Returns: the number of columns
  */
 glong
-vte_terminal_get_column_count(VteTerminal *terminal)
+vte_terminal_get_column_count(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        return IMPL(terminal)->m_column_count;
 }
+catch (...)
+{
+        vte::log_exception();
+        return -1;
+}
 
 /**
  * vte_terminal_get_current_directory_uri:
@@ -3850,12 +4378,18 @@ vte_terminal_get_column_count(VteTerminal *terminal)
  *   process running in the terminal, or %NULL
  */
 const char *
-vte_terminal_get_current_directory_uri(VteTerminal *terminal)
+vte_terminal_get_current_directory_uri(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
         auto impl = IMPL(terminal);
         return impl->m_current_directory_uri.size() ? impl->m_current_directory_uri.data() : nullptr;
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_get_current_file_uri:
@@ -3866,12 +4400,18 @@ vte_terminal_get_current_directory_uri(VteTerminal *terminal)
  *   not set
  */
 const char *
-vte_terminal_get_current_file_uri(VteTerminal *terminal)
+vte_terminal_get_current_file_uri(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
         auto impl = IMPL(terminal);
         return impl->m_current_file_uri.size() ? impl->m_current_file_uri.data() : nullptr;
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_get_cursor_blink_mode:
@@ -3882,12 +4422,18 @@ vte_terminal_get_current_file_uri(VteTerminal *terminal)
  * Return value: cursor blink mode.
  */
 VteCursorBlinkMode
-vte_terminal_get_cursor_blink_mode(VteTerminal *terminal)
+vte_terminal_get_cursor_blink_mode(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), VTE_CURSOR_BLINK_SYSTEM);
 
         return WIDGET(terminal)->cursor_blink_mode();
 }
+catch (...)
+{
+        vte::log_exception();
+        return VTE_CURSOR_BLINK_SYSTEM;
+}
 
 /**
  * vte_terminal_set_cursor_blink_mode:
@@ -3899,7 +4445,8 @@ vte_terminal_get_cursor_blink_mode(VteTerminal *terminal)
  */
 void
 vte_terminal_set_cursor_blink_mode(VteTerminal *terminal,
-                                   VteCursorBlinkMode mode)
+                                   VteCursorBlinkMode mode) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(mode >= VTE_CURSOR_BLINK_SYSTEM && mode <= VTE_CURSOR_BLINK_OFF);
@@ -3907,6 +4454,10 @@ vte_terminal_set_cursor_blink_mode(VteTerminal *terminal,
         if (WIDGET(terminal)->set_cursor_blink_mode(mode))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_CURSOR_BLINK_MODE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_cursor_shape:
@@ -3917,12 +4468,18 @@ vte_terminal_set_cursor_blink_mode(VteTerminal *terminal,
  * Return value: cursor shape.
  */
 VteCursorShape
-vte_terminal_get_cursor_shape(VteTerminal *terminal)
+vte_terminal_get_cursor_shape(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), VTE_CURSOR_SHAPE_BLOCK);
 
         return WIDGET(terminal)->cursor_shape();
 }
+catch (...)
+{
+        vte::log_exception();
+        return VTE_CURSOR_SHAPE_BLOCK;
+}
 
 /**
  * vte_terminal_set_cursor_shape:
@@ -3932,7 +4489,9 @@ vte_terminal_get_cursor_shape(VteTerminal *terminal)
  * Sets the shape of the cursor drawn.
  */
 void
-vte_terminal_set_cursor_shape(VteTerminal *terminal, VteCursorShape shape)
+vte_terminal_set_cursor_shape(VteTerminal *terminal,
+                              VteCursorShape shape) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(shape >= VTE_CURSOR_SHAPE_BLOCK && shape <= VTE_CURSOR_SHAPE_UNDERLINE);
@@ -3940,6 +4499,10 @@ vte_terminal_set_cursor_shape(VteTerminal *terminal, VteCursorShape shape)
         if (WIDGET(terminal)->set_cursor_shape(shape))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_CURSOR_SHAPE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_delete_binding:
@@ -3952,7 +4515,8 @@ vte_terminal_set_cursor_shape(VteTerminal *terminal, VteCursorShape shape)
  */
 void
 vte_terminal_set_delete_binding(VteTerminal *terminal,
-                                VteEraseBinding binding)
+                                VteEraseBinding binding) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(binding >= VTE_ERASE_AUTO && binding <= VTE_ERASE_TTY);
@@ -3960,6 +4524,10 @@ vte_terminal_set_delete_binding(VteTerminal *terminal,
         if (WIDGET(terminal)->set_delete_binding(binding))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_DELETE_BINDING]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_enable_bidi:
@@ -3972,11 +4540,17 @@ vte_terminal_set_delete_binding(VteTerminal *terminal,
  * Since: 0.58
  */
 gboolean
-vte_terminal_get_enable_bidi(VteTerminal *terminal)
+vte_terminal_get_enable_bidi(VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
         return IMPL(terminal)->m_enable_bidi;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_enable_bidi:
@@ -3989,13 +4563,18 @@ vte_terminal_get_enable_bidi(VteTerminal *terminal)
  */
 void
 vte_terminal_set_enable_bidi(VteTerminal *terminal,
-                             gboolean enable_bidi)
+                             gboolean enable_bidi) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_enable_bidi(enable_bidi != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_ENABLE_BIDI]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_enable_shaping:
@@ -4008,11 +4587,17 @@ vte_terminal_set_enable_bidi(VteTerminal *terminal,
  * Since: 0.58
  */
 gboolean
-vte_terminal_get_enable_shaping(VteTerminal *terminal)
+vte_terminal_get_enable_shaping(VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
         return IMPL(terminal)->m_enable_shaping;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_enable_shaping:
@@ -4025,13 +4610,18 @@ vte_terminal_get_enable_shaping(VteTerminal *terminal)
  */
 void
 vte_terminal_set_enable_shaping(VteTerminal *terminal,
-                                gboolean enable_shaping)
+                                gboolean enable_shaping) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_enable_shaping(enable_shaping != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_ENABLE_SHAPING]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_encoding:
@@ -4045,11 +4635,17 @@ vte_terminal_set_enable_shaping(VteTerminal *terminal,
  * Deprecated: 0.54: Support for non-UTF-8 is deprecated.
  */
 const char *
-vte_terminal_get_encoding(VteTerminal *terminal)
+vte_terminal_get_encoding(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
        return WIDGET(terminal)->encoding();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_set_encoding:
@@ -4073,23 +4669,26 @@ vte_terminal_get_encoding(VteTerminal *terminal)
 gboolean
 vte_terminal_set_encoding(VteTerminal *terminal,
                           const char *codeset,
-                          GError **error)
+                          GError **error) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
         g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
 
-        GObject *object = G_OBJECT(terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{terminal};
 
         auto const rv = IMPL(terminal)->set_encoding(codeset, error);
         if (rv) {
-                g_signal_emit(object, signals[SIGNAL_ENCODING_CHANGED], 0);
-                g_object_notify_by_pspec(object, pspecs[PROP_ENCODING]);
+                g_signal_emit(freezer.get(), signals[SIGNAL_ENCODING_CHANGED], 0);
+                g_object_notify_by_pspec(freezer.get(), pspecs[PROP_ENCODING]);
         }
 
-        g_object_thaw_notify(object);
         return rv;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /**
  * vte_terminal_get_font:
@@ -4104,12 +4703,18 @@ vte_terminal_set_encoding(VteTerminal *terminal,
  * terminal uses to render text at the default font scale of 1.0.
  */
 const PangoFontDescription *
-vte_terminal_get_font(VteTerminal *terminal)
+vte_terminal_get_font(VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
 
         return IMPL(terminal)->unscaled_font_description();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_set_font:
@@ -4124,13 +4729,18 @@ vte_terminal_get_font(VteTerminal *terminal)
  */
 void
 vte_terminal_set_font(VteTerminal *terminal,
-                      const PangoFontDescription *font_desc)
+                      const PangoFontDescription* font_desc) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_font_desc(font_desc))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_FONT_DESC]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_font_scale:
@@ -4139,12 +4749,18 @@ vte_terminal_set_font(VteTerminal *terminal,
  * Returns: the terminal's font scale
  */
 gdouble
-vte_terminal_get_font_scale(VteTerminal *terminal)
+vte_terminal_get_font_scale(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 1.);
 
         return IMPL(terminal)->m_font_scale;
 }
+catch (...)
+{
+        vte::log_exception();
+        return 1.;
+}
 
 /**
  * vte_terminal_set_font_scale:
@@ -4155,7 +4771,8 @@ vte_terminal_get_font_scale(VteTerminal *terminal)
  */
 void
 vte_terminal_set_font_scale(VteTerminal *terminal,
-                            double scale)
+                            double scale) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
@@ -4163,6 +4780,10 @@ vte_terminal_set_font_scale(VteTerminal *terminal,
         if (IMPL(terminal)->set_font_scale(scale))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_FONT_SCALE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_cell_height_scale:
@@ -4173,12 +4794,18 @@ vte_terminal_set_font_scale(VteTerminal *terminal,
  * Since: 0.52
  */
 double
-vte_terminal_get_cell_height_scale(VteTerminal *terminal)
+vte_terminal_get_cell_height_scale(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 1.);
 
         return IMPL(terminal)->m_cell_height_scale;
 }
+catch (...)
+{
+        vte::log_exception();
+        return 1.;
+}
 
 /**
  * vte_terminal_set_cell_height_scale:
@@ -4194,7 +4821,8 @@ vte_terminal_get_cell_height_scale(VteTerminal *terminal)
  */
 void
 vte_terminal_set_cell_height_scale(VteTerminal *terminal,
-                                   double scale)
+                                   double scale) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
@@ -4202,6 +4830,10 @@ vte_terminal_set_cell_height_scale(VteTerminal *terminal,
         if (IMPL(terminal)->set_cell_height_scale(scale))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_CELL_HEIGHT_SCALE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_cell_width_scale:
@@ -4212,12 +4844,18 @@ vte_terminal_set_cell_height_scale(VteTerminal *terminal,
  * Since: 0.52
  */
 double
-vte_terminal_get_cell_width_scale(VteTerminal *terminal)
+vte_terminal_get_cell_width_scale(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 1.);
 
         return IMPL(terminal)->m_cell_width_scale;
 }
+catch (...)
+{
+        vte::log_exception();
+        return 1.;
+}
 
 /**
  * vte_terminal_set_cell_width_scale:
@@ -4233,7 +4871,8 @@ vte_terminal_get_cell_width_scale(VteTerminal *terminal)
  */
 void
 vte_terminal_set_cell_width_scale(VteTerminal *terminal,
-                                  double scale)
+                                  double scale) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
@@ -4241,6 +4880,10 @@ vte_terminal_set_cell_width_scale(VteTerminal *terminal,
         if (IMPL(terminal)->set_cell_width_scale(scale))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_CELL_WIDTH_SCALE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /* Just some arbitrary minimum values */
 #define MIN_COLUMNS (16)
@@ -4267,7 +4910,7 @@ void
 vte_terminal_get_geometry_hints(VteTerminal *terminal,
                                 GdkGeometry *hints,
                                 int min_rows,
-                                int min_columns)
+                                int min_columns) noexcept
 {
         GtkWidget *widget;
         GtkBorder padding;
@@ -4316,7 +4959,7 @@ vte_terminal_get_geometry_hints(VteTerminal *terminal,
  */
 void
 vte_terminal_set_geometry_hints_for_window(VteTerminal *terminal,
-                                           GtkWindow *window)
+                                           GtkWindow *window) noexcept
 {
         GdkGeometry hints;
 
@@ -4343,11 +4986,17 @@ vte_terminal_set_geometry_hints_for_window(VteTerminal *terminal,
  * Returns: %TRUE if part of the text in the terminal is selected.
  */
 gboolean
-vte_terminal_get_has_selection(VteTerminal *terminal)
+vte_terminal_get_has_selection(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
         return !IMPL(terminal)->m_selection_resolved.empty();
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_get_icon_title:
@@ -4358,7 +5007,7 @@ vte_terminal_get_has_selection(VteTerminal *terminal)
  * Deprecated: 0.54:
  */
 const char *
-vte_terminal_get_icon_title(VteTerminal *terminal)
+vte_terminal_get_icon_title(VteTerminal *terminal) noexcept
 {
        return nullptr;
 }
@@ -4370,12 +5019,18 @@ vte_terminal_get_icon_title(VteTerminal *terminal)
  * Returns whether the terminal allow user input.
  */
 gboolean
-vte_terminal_get_input_enabled (VteTerminal *terminal)
+vte_terminal_get_input_enabled (VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
 
         return IMPL(terminal)->m_input_enabled;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_input_enabled:
@@ -4388,13 +5043,18 @@ vte_terminal_get_input_enabled (VteTerminal *terminal)
  */
 void
 vte_terminal_set_input_enabled (VteTerminal *terminal,
-                                gboolean enabled)
+                                gboolean enabled) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_input_enabled(enabled != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_INPUT_ENABLED]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_mouse_autohide:
@@ -4408,11 +5068,17 @@ vte_terminal_set_input_enabled (VteTerminal *terminal,
  * Returns: %TRUE if autohiding is enabled, %FALSE if not
  */
 gboolean
-vte_terminal_get_mouse_autohide(VteTerminal *terminal)
+vte_terminal_get_mouse_autohide(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_mouse_autohide;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_mouse_autohide:
@@ -4425,13 +5091,19 @@ vte_terminal_get_mouse_autohide(VteTerminal *terminal)
  * vte_terminal_get_mouse_autohide().
  */
 void
-vte_terminal_set_mouse_autohide(VteTerminal *terminal, gboolean setting)
+vte_terminal_set_mouse_autohide(VteTerminal *terminal,
+                                gboolean setting) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_mouse_autohide(setting != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_MOUSE_POINTER_AUTOHIDE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_set_pty:
@@ -4443,18 +5115,20 @@ vte_terminal_set_mouse_autohide(VteTerminal *terminal, gboolean setting)
  */
 void
 vte_terminal_set_pty(VteTerminal *terminal,
-                     VtePty *pty)
+                     VtePty *pty) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(pty == NULL || VTE_IS_PTY(pty));
 
-        GObject *object = G_OBJECT(terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{terminal};
 
         if (WIDGET(terminal)->set_pty(pty))
-                g_object_notify_by_pspec(object, pspecs[PROP_PTY]);
-
-        g_object_thaw_notify(object);
+                g_object_notify_by_pspec(freezer.get(), pspecs[PROP_PTY]);
+}
+catch (...)
+{
+        vte::log_exception();
 }
 
 /**
@@ -4466,12 +5140,17 @@ vte_terminal_set_pty(VteTerminal *terminal,
  * Returns: (transfer none): a #VtePty, or %NULL
  */
 VtePty *
-vte_terminal_get_pty(VteTerminal *terminal)
+vte_terminal_get_pty(VteTerminal *terminal) noexcept
+try
 {
-        g_return_val_if_fail (VTE_IS_TERMINAL (terminal), NULL);
-
+        g_return_val_if_fail (VTE_IS_TERMINAL (terminal), nullptr);
         return WIDGET(terminal)->pty();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_get_rewrap_on_resize:
@@ -4484,11 +5163,17 @@ vte_terminal_get_pty(VteTerminal *terminal)
  * Deprecated: 0.58
  */
 gboolean
-vte_terminal_get_rewrap_on_resize(VteTerminal *terminal)
+vte_terminal_get_rewrap_on_resize(VteTerminal *terminal) noexcept
+try
 {
-       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
        return IMPL(terminal)->m_rewrap_on_resize;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_rewrap_on_resize:
@@ -4502,13 +5187,18 @@ vte_terminal_get_rewrap_on_resize(VteTerminal *terminal)
  */
 void
 vte_terminal_set_rewrap_on_resize(VteTerminal *terminal,
-                                  gboolean rewrap)
+                                  gboolean rewrap) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_rewrap_on_resize(rewrap != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_REWRAP_ON_RESIZE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_row_count:
@@ -4518,11 +5208,17 @@ vte_terminal_set_rewrap_on_resize(VteTerminal *terminal,
  * Returns: the number of rows
  */
 glong
-vte_terminal_get_row_count(VteTerminal *terminal)
+vte_terminal_get_row_count(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        return IMPL(terminal)->m_row_count;
 }
+catch (...)
+{
+        vte::log_exception();
+        return -1;
+}
 
 /**
  * vte_terminal_set_scrollback_lines:
@@ -4540,18 +5236,21 @@ vte_terminal_get_row_count(VteTerminal *terminal)
  * No scrollback is allowed on the alternate screen buffer.
  */
 void
-vte_terminal_set_scrollback_lines(VteTerminal *terminal, glong lines)
+vte_terminal_set_scrollback_lines(VteTerminal *terminal,
+                                  glong lines) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(lines >= -1);
 
-        GObject *object = G_OBJECT(terminal);
-        g_object_freeze_notify(object);
+        auto const freezer = vte::glib::FreezeObjectNotify{terminal};
 
         if (IMPL(terminal)->set_scrollback_lines(lines))
-                g_object_notify_by_pspec(object, pspecs[PROP_SCROLLBACK_LINES]);
-
-        g_object_thaw_notify(object);
+                g_object_notify_by_pspec(freezer.get(), pspecs[PROP_SCROLLBACK_LINES]);
+}
+catch (...)
+{
+        vte::log_exception();
 }
 
 /**
@@ -4564,11 +5263,17 @@ vte_terminal_set_scrollback_lines(VteTerminal *terminal, glong lines)
  * Since: 0.52
  */
 glong
-vte_terminal_get_scrollback_lines(VteTerminal *terminal)
+vte_terminal_get_scrollback_lines(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 0);
         return IMPL(terminal)->m_scrollback_lines;
 }
+catch (...)
+{
+        vte::log_exception();
+        return 0;
+}
 
 /**
  * vte_terminal_set_scroll_on_keystroke:
@@ -4581,13 +5286,18 @@ vte_terminal_get_scrollback_lines(VteTerminal *terminal)
  */
 void
 vte_terminal_set_scroll_on_keystroke(VteTerminal *terminal,
-                                     gboolean scroll)
+                                     gboolean scroll) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_scroll_on_keystroke(scroll != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_SCROLL_ON_KEYSTROKE]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_scroll_on_keystroke:
@@ -4600,11 +5310,17 @@ vte_terminal_set_scroll_on_keystroke(VteTerminal *terminal,
  * Since: 0.52
  */
 gboolean
-vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal)
+vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal) noexcept
+try
 {
-    g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+    g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
     return IMPL(terminal)->m_scroll_on_keystroke;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_set_scroll_on_output:
@@ -4616,13 +5332,18 @@ vte_terminal_get_scroll_on_keystroke(VteTerminal *terminal)
  */
 void
 vte_terminal_set_scroll_on_output(VteTerminal *terminal,
-                                  gboolean scroll)
+                                  gboolean scroll) noexcept
+try
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         if (IMPL(terminal)->set_scroll_on_output(scroll != FALSE))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_SCROLL_ON_OUTPUT]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_scroll_on_output:
@@ -4634,11 +5355,17 @@ vte_terminal_set_scroll_on_output(VteTerminal *terminal,
  * Since: 0.52
  */
 gboolean
-vte_terminal_get_scroll_on_output(VteTerminal *terminal)
+vte_terminal_get_scroll_on_output(VteTerminal *terminal) noexcept
+try
 {
-    g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+    g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
     return IMPL(terminal)->m_scroll_on_output;
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 /**
  * vte_terminal_get_window_title:
@@ -4647,11 +5374,17 @@ vte_terminal_get_scroll_on_output(VteTerminal *terminal)
  * Returns: (nullable) (transfer none): the window title, or %NULL
  */
 const char *
-vte_terminal_get_window_title(VteTerminal *terminal)
+vte_terminal_get_window_title(VteTerminal *terminal) noexcept
+try
 {
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
        return IMPL(terminal)->m_window_title.data();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_get_word_char_exceptions:
@@ -4668,12 +5401,18 @@ vte_terminal_get_window_title(VteTerminal *terminal)
  * Since: 0.40
  */
 const char *
-vte_terminal_get_word_char_exceptions(VteTerminal *terminal)
+vte_terminal_get_word_char_exceptions(VteTerminal *terminal) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
 
         return WIDGET(terminal)->word_char_exceptions();
 }
+catch (...)
+{
+        vte::log_exception();
+        return nullptr;
+}
 
 /**
  * vte_terminal_set_word_char_exceptions:
@@ -4695,7 +5434,8 @@ vte_terminal_get_word_char_exceptions(VteTerminal *terminal)
  */
 void
 vte_terminal_set_word_char_exceptions(VteTerminal *terminal,
-                                      const char *exceptions)
+                                      const char *exceptions) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
@@ -4703,6 +5443,10 @@ vte_terminal_set_word_char_exceptions(VteTerminal *terminal,
         if (WIDGET(terminal)->set_word_char_exceptions(stropt))
                 g_object_notify_by_pspec(G_OBJECT(terminal), pspecs[PROP_WORD_CHAR_EXCEPTIONS]);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_write_contents_sync:
@@ -4730,13 +5474,18 @@ vte_terminal_write_contents_sync (VteTerminal *terminal,
                                   GOutputStream *stream,
                                   VteWriteFlags flags,
                                   GCancellable *cancellable,
-                                  GError **error)
+                                  GError **error) noexcept
+try
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
-        g_return_val_if_fail(G_IS_OUTPUT_STREAM(stream), FALSE);
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), false);
+        g_return_val_if_fail(G_IS_OUTPUT_STREAM(stream), false);
 
         return IMPL(terminal)->write_contents_sync(stream, flags, cancellable, error);
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /**
  * vte_terminal_set_clear_background:
@@ -4753,12 +5502,17 @@ vte_terminal_write_contents_sync (VteTerminal *terminal,
  */
 void
 vte_terminal_set_clear_background(VteTerminal* terminal,
-                                  gboolean setting)
+                                  gboolean setting) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
         IMPL(terminal)->set_clear_background(setting != FALSE);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_terminal_get_color_background_for_draw:
@@ -4780,7 +5534,8 @@ vte_terminal_set_clear_background(VteTerminal* terminal,
  */
 void
 vte_terminal_get_color_background_for_draw(VteTerminal* terminal,
-                                           GdkRGBA* color)
+                                           GdkRGBA* color) noexcept
+try
 {
         g_return_if_fail(VTE_IS_TERMINAL(terminal));
         g_return_if_fail(color != nullptr);
@@ -4792,3 +5547,102 @@ vte_terminal_get_color_background_for_draw(VteTerminal* terminal,
         color->blue = c->blue / 65535.;
         color->alpha = impl->m_background_alpha;
 }
+catch (...)
+{
+        vte::log_exception();
+        *color = {0., 0., 0., 1.};
+}
+
+namespace vte {
+
+using namespace std::literals;
+
+static void
+exception_append_to_string(std::exception const& e,
+                           std::string& what,
+                           int level = 0)
+{
+        if (level > 0)
+                what += ": "sv;
+        what += e.what();
+
+        try {
+                std::rethrow_if_nested(e);
+        } catch (std::exception const& en) {
+                exception_append_to_string(en, what, level + 1);
+        } catch (...) {
+                what += ": Unknown nested exception"sv;
+        }
+}
+
+#ifdef VTE_DEBUG
+void log_exception(char const* func,
+                   char const* filename,
+                   int const line) noexcept
+try
+{
+        auto what = std::string{};
+
+        try {
+                throw; // rethrow current exception
+        } catch (std::exception const& e) {
+                exception_append_to_string(e, what);
+        } catch (...) {
+                what = "Unknown exception"sv;
+        }
+
+        _vte_debug_print(VTE_DEBUG_EXCEPTIONS,
+                         "Caught exception in %s [%s:%d]: %s\n",
+                         func, filename, line, what.c_str());
+}
+catch (...)
+{
+        _vte_debug_print(VTE_DEBUG_EXCEPTIONS,
+                         "Caught exception while logging an exception in %s [%s:%d]\n",
+                         func, filename, line);
+}
+#endif /* VTE_DEBUG */
+
+namespace glib {
+
+bool set_error_from_exception(GError** error
+#ifdef VTE_DEBUG
+                              , char const* func
+                              , char const* filename
+                              , int const line
+#endif
+                              ) noexcept
+try
+{
+        auto what = std::string{};
+
+        try {
+                throw; // rethrow current exception
+        } catch (std::exception const& e) {
+                exception_append_to_string(e, what);
+        } catch (...) {
+                what = "Unknown exception"sv;
+        }
+
+        auto msg = vte::glib::take_string(g_strdup_printf("Caught exception in %s [%s:%d]: %s",
+                                                          func, filename, line, what.c_str()));
+        auto msg_str = vte::glib::take_string(g_utf8_make_valid(msg.get(), -1));
+        g_set_error_literal(error,
+                            G_IO_ERROR,
+                            G_IO_ERROR_FAILED,
+                            msg_str.get());
+        _vte_debug_print(VTE_DEBUG_EXCEPTIONS, "%s", msg_str.get());
+
+        return false;
+}
+catch (...)
+{
+        vte::log_exception();
+        g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                    "Caught exception while logging an exception in %s [%s:%d]\n",
+                    func, filename, line);
+        return false;
+}
+
+} // namespace glib
+} // namespace vte
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 33cfde3c..bfb7e5ed 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -74,17 +74,6 @@ enum {
 
 namespace vte {
 
-// This is like std::clamp, except that it doesn't throw when
-// max_v<min_v, but instead returns min_v in that case.
-template<typename T>
-constexpr inline T const&
-clamp(T const& v,
-      T const& min_v,
-      T const& max_v)
-{
-        return std::max(std::min(v, max_v), min_v);
-}
-
 namespace platform {
 
 /*
@@ -594,7 +583,7 @@ public:
         int m_child_exit_status{-1};   /* pid's exit status, or -1 */
         bool m_eos_pending{false};
         bool m_child_exited_after_eos_pending{false};
-        bool child_exited_eos_wait_callback() noexcept;
+        bool child_exited_eos_wait_callback();
         vte::glib::Timer m_child_exited_eos_wait_timer{std::bind(&Terminal::child_exited_eos_wait_callback,
                                                                  this),
                                                        "child-exited-eos-wait-timer"};
@@ -718,6 +707,7 @@ public:
         double m_cursor_aspect_ratio{0.04};
 
        /* Cursor blinking */
+        bool cursor_blink_timer_callback();
         vte::glib::Timer m_cursor_blink_timer{std::bind(&Terminal::cursor_blink_timer_callback,
                                                         this),
                                               "cursor-blink-timer"};
@@ -730,7 +720,7 @@ public:
         bool m_has_focus{false};            /* is the widget focused */
 
         /* Contents blinking */
-        bool text_blink_timer_callback() noexcept;
+        bool text_blink_timer_callback();
         vte::glib::Timer m_text_blink_timer{std::bind(&Terminal::text_blink_timer_callback,
                                                       this),
                                             "text-blink-timer"};
@@ -757,7 +747,7 @@ public:
          */
         vte::view::coords m_mouse_last_position{-1, -1};
         double m_mouse_smooth_scroll_delta{0.0};
-        bool mouse_autoscroll_timer_callback() noexcept;
+        bool mouse_autoscroll_timer_callback();
         vte::glib::Timer m_mouse_autoscroll_timer{std::bind(&Terminal::mouse_autoscroll_timer_callback,
                                                             this),
                                                   "mouse-autoscroll-timer"};
@@ -1063,7 +1053,6 @@ public:
         gssize get_preedit_length(bool left_only);
 
         void invalidate_cursor_once(bool periodic = false);
-        bool cursor_blink_timer_callback() noexcept;
         void check_cursor_blink();
         void add_cursor_timeout();
         void remove_cursor_timeout();
diff --git a/src/vtepty.cc b/src/vtepty.cc
index 1f79a0d0..b2ed5570 100644
--- a/src/vtepty.cc
+++ b/src/vtepty.cc
@@ -26,7 +26,9 @@
  * pseudo-terminals and to resize pseudo-terminals.
  */
 
-#include <config.h>
+#include "config.h"
+
+#include <exception>
 
 #include <vte/vte.h>
 
@@ -37,8 +39,10 @@
 
 #include <glib/gi18n-lib.h>
 
+#include "cxx-utils.hh"
 #include "libc-glue.hh"
 #include "pty.hh"
+#include "refptr.hh"
 #include "spawn.hh"
 
 #include "vteptyinternal.hh"
@@ -126,7 +130,8 @@ _vte_pty_get_impl(VtePty* pty)
  * @pty: a #VtePty
  */
 void
-vte_pty_child_setup (VtePty *pty)
+vte_pty_child_setup (VtePty *pty) noexcept
+try
 {
         g_return_if_fail(pty != nullptr);
         auto impl = IMPL(pty);
@@ -134,6 +139,10 @@ vte_pty_child_setup (VtePty *pty)
 
         impl->child_setup();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 /**
  * vte_pty_set_size:
@@ -153,7 +162,8 @@ gboolean
 vte_pty_set_size(VtePty *pty,
                  int rows,
                  int columns,
-                 GError **error)
+                 GError **error) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_PTY(pty), FALSE);
         auto impl = IMPL(pty);
@@ -170,6 +180,10 @@ vte_pty_set_size(VtePty *pty,
 
         return false;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /**
  * vte_pty_get_size:
@@ -188,7 +202,8 @@ gboolean
 vte_pty_get_size(VtePty *pty,
                  int *rows,
                  int *columns,
-                 GError **error)
+                 GError **error) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_PTY(pty), FALSE);
         auto impl = IMPL(pty);
@@ -204,6 +219,10 @@ vte_pty_get_size(VtePty *pty,
                     g_strerror(errsv));
         return false;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /**
  * vte_pty_set_utf8:
@@ -220,7 +239,8 @@ vte_pty_get_size(VtePty *pty,
 gboolean
 vte_pty_set_utf8(VtePty *pty,
                  gboolean utf8,
-                 GError **error)
+                 GError **error) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_PTY(pty), FALSE);
         auto impl = IMPL(pty);
@@ -234,6 +254,10 @@ vte_pty_set_utf8(VtePty *pty,
                     "%s failed: %s", "tc[sg]etattr", g_strerror(errsv));
         return false;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /**
  * vte_pty_close:
@@ -244,7 +268,7 @@ vte_pty_set_utf8(VtePty *pty,
  * Deprecated: 0.42
  */
 void
-vte_pty_close (VtePty *pty)
+vte_pty_close (VtePty *pty) noexcept
 {
         /* impl->close(); */
 }
@@ -262,7 +286,8 @@ enum {
 static gboolean
 vte_pty_initable_init (GInitable *initable,
                        GCancellable *cancellable,
-                       GError **error)
+                       GError **error) noexcept
+try
 {
         VtePty *pty = VTE_PTY (initable);
         VtePtyPrivate *priv = pty->priv;
@@ -283,6 +308,10 @@ vte_pty_initable_init (GInitable *initable,
 
         return !g_cancellable_set_error_if_cancelled(cancellable, error);
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 static void
 vte_pty_initable_iface_init (GInitableIface  *iface)
@@ -309,16 +338,20 @@ vte_pty_init (VtePty *pty)
 }
 
 static void
-vte_pty_finalize (GObject *object)
+vte_pty_finalize (GObject *object) noexcept
+try
 {
         VtePty *pty = VTE_PTY (object);
         VtePtyPrivate *priv = pty->priv;
 
-        if (priv->pty != nullptr)
-                priv->pty->unref();
+        auto implptr = vte::base::RefPtr<vte::base::Pty>{priv->pty}; // moved
 
         G_OBJECT_CLASS (vte_pty_parent_class)->finalize (object);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 vte_pty_get_property (GObject    *object,
@@ -416,7 +449,7 @@ vte_pty_class_init (VtePtyClass *klass)
  * Returns: the error domain for VTE PTY errors
  */
 GQuark
-vte_pty_error_quark(void)
+vte_pty_error_quark(void) noexcept
 {
   static GQuark quark = 0;
 
@@ -464,7 +497,7 @@ vte_pty_error_quark(void)
 VtePty *
 vte_pty_new_sync (VtePtyFlags flags,
                   GCancellable *cancellable,
-                  GError **error)
+                  GError **error) noexcept
 {
         return (VtePty *) g_initable_new (VTE_TYPE_PTY,
                                           cancellable,
@@ -491,7 +524,7 @@ vte_pty_new_sync (VtePtyFlags flags,
 VtePty *
 vte_pty_new_foreign_sync (int fd,
                           GCancellable *cancellable,
-                          GError **error)
+                          GError **error) noexcept
 {
         g_return_val_if_fail(fd != -1, nullptr);
 
@@ -511,17 +544,20 @@ vte_pty_new_foreign_sync (int fd,
  *   its flags changed
  */
 int
-vte_pty_get_fd (VtePty *pty)
+vte_pty_get_fd (VtePty *pty) noexcept
+try
 {
         g_return_val_if_fail(VTE_IS_PTY(pty), FALSE);
-        auto impl = IMPL(pty);
-        g_return_val_if_fail(impl != nullptr, FALSE);
-
-        return impl->fd();
+        return IMPL(pty)->fd();
+}
+catch (...)
+{
+        vte::log_exception();
+        return -1;
 }
 
 static constexpr inline auto
-all_spawn_flags()
+all_spawn_flags() noexcept
 {
         return GSpawnFlags(G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
                            G_SPAWN_DO_NOT_REAP_CHILD |
@@ -538,7 +574,7 @@ all_spawn_flags()
 }
 
 static constexpr inline auto
-forbidden_spawn_flags()
+forbidden_spawn_flags() noexcept
 {
         return GSpawnFlags(G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
                            G_SPAWN_STDOUT_TO_DEV_NULL |
@@ -547,7 +583,7 @@ forbidden_spawn_flags()
 }
 
 static constexpr inline auto
-ignored_spawn_flags()
+ignored_spawn_flags() noexcept
 {
         return GSpawnFlags(G_SPAWN_CLOEXEC_PIPES |
                            G_SPAWN_DO_NOT_REAP_CHILD);
@@ -610,7 +646,8 @@ _vte_pty_spawn_sync(VtePty* pty,
                     GPid* child_pid /* out */,
                     int timeout,
                     GCancellable* cancellable,
-                    GError** error)
+                    GError** error) noexcept
+try
 {
         /* These are ignored or need not be passed since the behaviour is the default */
         g_warn_if_fail((spawn_flags & ignored_spawn_flags()) == 0);
@@ -639,6 +676,10 @@ _vte_pty_spawn_sync(VtePty* pty,
 
         return rv;
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 /*
  * _vte_pty_check_envv:
@@ -647,7 +688,7 @@ _vte_pty_spawn_sync(VtePty* pty,
  * Validates that each element is of the form 'KEY=VALUE'.
  */
 bool
-_vte_pty_check_envv(char const* const* strv)
+_vte_pty_check_envv(char const* const* strv) noexcept
 {
   if (!strv)
     return true;
@@ -733,7 +774,8 @@ vte_pty_spawn_with_fds_async(VtePty *pty,
                              int timeout,
                              GCancellable *cancellable,
                              GAsyncReadyCallback callback,
-                             gpointer user_data)
+                             gpointer user_data) noexcept
+try
 {
         g_return_if_fail(argv != nullptr);
         g_return_if_fail(argv[0] != nullptr);
@@ -775,6 +817,13 @@ vte_pty_spawn_with_fds_async(VtePty *pty,
                       callback,
                       user_data);
 }
+catch (...)
+{
+        // FIXME: make the function above exception safe. It needs to guarantee
+        // that the callback will be invoked regardless of when the throw occurred.
+
+        vte::log_exception();
+}
 
 /**
  * vte_pty_spawn_async:
@@ -809,7 +858,7 @@ vte_pty_spawn_async(VtePty *pty,
                     int timeout,
                     GCancellable *cancellable,
                     GAsyncReadyCallback callback,
-                    gpointer user_data)
+                    gpointer user_data) noexcept
 {
         vte_pty_spawn_with_fds_async(pty, working_directory, argv, envv,
                                      nullptr, 0, nullptr, 0,
@@ -834,7 +883,7 @@ gboolean
 vte_pty_spawn_finish(VtePty* pty,
                      GAsyncResult* result,
                      GPid* child_pid /* out */,
-                     GError** error)
+                     GError** error) noexcept
 {
         g_return_val_if_fail (VTE_IS_PTY(pty), false);
         g_return_val_if_fail (G_IS_TASK(result), false);
diff --git a/src/vteptyinternal.hh b/src/vteptyinternal.hh
index 7e1a8b5d..0c78d895 100644
--- a/src/vteptyinternal.hh
+++ b/src/vteptyinternal.hh
@@ -33,6 +33,6 @@ bool _vte_pty_spawn_sync(VtePty* pty,
                          GPid* child_pid /* out */,
                          int timeout,
                          GCancellable* cancellable,
-                         GError** error);
+                         GError** error) noexcept;
 
-bool _vte_pty_check_envv(char const* const* envv);
+bool _vte_pty_check_envv(char const* const* envv) noexcept;
diff --git a/src/vteregex.cc b/src/vteregex.cc
index 26a55b43..a125df55 100644
--- a/src/vteregex.cc
+++ b/src/vteregex.cc
@@ -24,6 +24,8 @@
 
 #include "config.h"
 
+#include <exception>
+
 #include "vtemacros.h"
 #include "vteenums.h"
 #include "vteregex.h"
@@ -31,6 +33,8 @@
 
 #include "regex.hh"
 #include "vteregexinternal.hh"
+#include "glib-glue.hh"
+#include "cxx-utils.hh"
 
 #define IMPL(wrapper) (regex_from_wrapper(wrapper))
 
@@ -55,7 +59,7 @@ G_DEFINE_QUARK(vte-regex-error, vte_regex_error)
  * Returns: @regex
  */
 VteRegex *
-vte_regex_ref(VteRegex *regex)
+vte_regex_ref(VteRegex *regex) noexcept
 {
         g_return_val_if_fail(regex != nullptr, nullptr);
 
@@ -72,7 +76,7 @@ vte_regex_ref(VteRegex *regex)
  * Returns: %NULL
  */
 VteRegex *
-vte_regex_unref(VteRegex* regex)
+vte_regex_unref(VteRegex* regex) noexcept
 {
         g_return_val_if_fail(regex != nullptr, nullptr);
 
@@ -84,10 +88,16 @@ static VteRegex*
 vte_regex_new(vte::base::Regex::Purpose purpose,
               std::string_view const& pattern,
               uint32_t flags,
-              GError** error)
+              GError** error) noexcept
+try
 {
         return wrapper_from_regex(vte::base::Regex::compile(purpose, pattern, flags, error));
 }
+catch (...)
+{
+        vte::glib::set_error_from_exception(error);
+        return nullptr;
+}
 
 /**
  * vte_regex_new_for_match:
@@ -113,7 +123,8 @@ VteRegex *
 vte_regex_new_for_match(const char *pattern,
                         gssize      pattern_length,
                         guint32     flags,
-                        GError    **error)
+                        GError    **error) noexcept
+try
 {
         auto const len = size_t{pattern_length == -1 ? strlen(pattern) : size_t(pattern_length)};
         return vte_regex_new(vte::base::Regex::Purpose::eMatch,
@@ -121,6 +132,11 @@ vte_regex_new_for_match(const char *pattern,
                              flags,
                              error);
 }
+catch (...)
+{
+        vte::glib::set_error_from_exception(error);
+        return nullptr;
+}
 
 /**
  * vte_regex_new_for_search:
@@ -145,7 +161,8 @@ VteRegex *
 vte_regex_new_for_search(const char *pattern,
                          gssize      pattern_length,
                          guint32     flags,
-                         GError    **error)
+                         GError    **error) noexcept
+try
 {
         auto const len = size_t{pattern_length == -1 ? strlen(pattern) : size_t(pattern_length)};
         return vte_regex_new(vte::base::Regex::Purpose::eSearch,
@@ -153,6 +170,11 @@ vte_regex_new_for_search(const char *pattern,
                              flags,
                              error);
 }
+catch (...)
+{
+        vte::glib::set_error_from_exception(error);
+        return nullptr;
+}
 
 /**
  * vte_regex_jit:
@@ -166,12 +188,17 @@ vte_regex_new_for_search(const char *pattern,
 gboolean
 vte_regex_jit(VteRegex *regex,
               guint     flags,
-              GError  **error)
+              GError  **error) noexcept
+try
 {
         g_return_val_if_fail(regex != nullptr, false);
 
         return IMPL(regex)->jit(flags, error);
 }
+catch (...)
+{
+        return vte::glib::set_error_from_exception(error);
+}
 
 bool
 _vte_regex_has_purpose(VteRegex *regex,
@@ -210,7 +237,8 @@ vte_regex_substitute(VteRegex *regex,
                      const char *subject,
                      const char *replacement,
                      guint32 flags,
-                     GError **error)
+                     GError **error) noexcept
+try
 {
         g_return_val_if_fail(regex != nullptr, nullptr);
         g_return_val_if_fail(subject != nullptr, nullptr);
@@ -220,3 +248,8 @@ vte_regex_substitute(VteRegex *regex,
         auto const r = IMPL(regex)->substitute(subject, replacement, flags, error);
         return r ? g_strndup(r->c_str(), r->size()) : nullptr;
 }
+catch (...)
+{
+        vte::glib::set_error_from_exception(error);
+        return nullptr;
+}
diff --git a/src/widget.cc b/src/widget.cc
index 3a22d219..2967d93a 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -22,9 +22,11 @@
 
 #include <sys/wait.h> // for W_EXITCODE
 
+#include <exception>
 #include <new>
 #include <string>
 
+#include "cxx-utils.hh"
 #include "vtegtk.hh"
 #include "vteptyinternal.hh"
 #include "debug.h"
@@ -38,70 +40,106 @@ namespace platform {
 static void
 im_commit_cb(GtkIMContext* im_context,
              char const* text,
-             Widget* that)
+             Widget* that) noexcept
+try
 {
         if (text == nullptr)
                 return;
 
         that->terminal()->im_commit(text);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 im_preedit_start_cb(GtkIMContext* im_context,
-                    Widget* that)
+                    Widget* that) noexcept
+try
 {
         _vte_debug_print(VTE_DEBUG_EVENTS, "Input method pre-edit started.\n");
         that->terminal()->im_preedit_set_active(true);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 im_preedit_end_cb(GtkIMContext* im_context,
-                  Widget* that)
+                  Widget* that) noexcept
+try
 {
         _vte_debug_print(VTE_DEBUG_EVENTS, "Input method pre-edit ended.\n");
         that->terminal()->im_preedit_set_active(false);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static void
 im_preedit_changed_cb(GtkIMContext* im_context,
-                      Widget* that)
+                      Widget* that) noexcept
+try
 {
         that->im_preedit_changed();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 static gboolean
 im_retrieve_surrounding_cb(GtkIMContext* im_context,
-                           Widget* that)
+                           Widget* that) noexcept
+try
 {
         _vte_debug_print(VTE_DEBUG_EVENTS, "Input method retrieve-surrounding.\n");
         return that->terminal()->im_retrieve_surrounding();
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static gboolean
 im_delete_surrounding_cb(GtkIMContext* im_context,
                          int offset,
                          int n_chars,
-                         Widget* that)
+                         Widget* that) noexcept
+try
 {
         _vte_debug_print(VTE_DEBUG_EVENTS,
                          "Input method delete-surrounding offset %d n-chars %d.\n",
                          offset, n_chars);
         return that->terminal()->im_delete_surrounding(offset, n_chars);
 }
+catch (...)
+{
+        vte::log_exception();
+        return false;
+}
 
 static void
 settings_notify_cb(GtkSettings* settings,
                    GParamSpec* pspec,
-                   vte::platform::Widget* that)
+                   vte::platform::Widget* that) noexcept
+try
 {
         that->settings_changed();
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
-Widget::Widget(VteTerminal* t) noexcept :
-        m_widget{&t->widget},
-        m_hscroll_policy{GTK_SCROLL_NATURAL},
-        m_vscroll_policy{GTK_SCROLL_NATURAL}
-
+Widget::Widget(VteTerminal* t)
+        : m_widget{&t->widget},
+          m_hscroll_policy{GTK_SCROLL_NATURAL},
+          m_vscroll_policy{GTK_SCROLL_NATURAL}
 {
         gtk_widget_set_can_focus(gtk(), true);
 
@@ -115,6 +153,7 @@ Widget::Widget(VteTerminal* t) noexcept :
 }
 
 Widget::~Widget() noexcept
+try
 {
         g_signal_handlers_disconnect_matched(gtk_widget_get_settings(m_widget),
                                              G_SIGNAL_MATCH_DATA,
@@ -126,6 +165,10 @@ Widget::~Widget() noexcept
         m_terminal->~Terminal();
         g_free(m_terminal);
 }
+catch (...)
+{
+        vte::log_exception();
+}
 
 void
 Widget::beep() noexcept
diff --git a/src/widget.hh b/src/widget.hh
index 8e7d1c73..0025d5bb 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -44,7 +44,7 @@ class Widget {
 public:
         friend class vte::terminal::Terminal;
 
-        Widget(VteTerminal* t) noexcept;
+        Widget(VteTerminal* t);
         ~Widget() noexcept;
 
         Widget(Widget const&) = delete;


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