lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 83b3c83: Rename fatal_error()


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 83b3c83: Rename fatal_error()
Date: Thu, 2 Mar 2017 20:02:34 -0500 (EST)

branch: master
commit 83b3c835300d5bc515a99db447bdefdacf615dca
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Rename fatal_error()
    
    It doesn't cause termination, so the name was misleading. It might seem
    natural to use error() as the new name, but that is fatally ungreppable.
---
 accountvalue.cpp           |  20 +++---
 actuarial_table.cpp        |  14 ++--
 alert.cpp                  |  22 +++----
 alert.hpp                  |  24 +++----
 alert_cgi.cpp              |   4 +-
 alert_cli.cpp              |   4 +-
 alert_test.cpp             |  18 +++---
 alert_wx.cpp               |   4 +-
 authenticity.cpp           |   2 +-
 basicvalues.cpp            |   4 +-
 calendar_date.cpp          |  12 ++--
 calendar_date_test.cpp     |   2 +-
 ce_product_name.cpp        |   4 +-
 ce_skin_name.cpp           |   4 +-
 census_view.cpp            |  16 ++---
 configurable_settings.cpp  |   4 +-
 custom_io_0.cpp            |  16 ++---
 custom_io_1.cpp            |   6 +-
 database_view_editor.cpp   |   4 +-
 dbdict.cpp                 |   4 +-
 dbvalue.cpp                |  14 ++--
 file_command_cgi.cpp       |   2 +-
 file_command_cli.cpp       |   2 +-
 file_command_wx.cpp        |  18 ++----
 fund_data.cpp              |   2 +-
 global_settings.cpp        |   2 +-
 gpt_input.cpp              |   4 +-
 gpt_server.cpp             |   4 +-
 group_quote_pdf_gen_wx.cpp |  20 +++---
 group_values.cpp           |  10 +--
 ihs_acctval.cpp            |  10 +--
 ihs_avmly.cpp              |  59 +++++++----------
 ihs_avsolve.cpp            |   7 +-
 ihs_avstrtgy.cpp           |   6 +-
 ihs_basicval.cpp           |  42 ++++++------
 ihs_irc7702.cpp            |   9 +--
 ihs_irc7702a.cpp           |   8 +--
 ihs_mortal.cpp             |  12 ++--
 illustrator.cpp            |   8 +--
 input_harmonization.cpp    |  14 ++--
 input_realization.cpp      |   7 +-
 input_sequence.cpp         |  27 ++++----
 input_sequence_aux.hpp     |   2 +-
 input_sequence_entry.cpp   |  10 +--
 input_xml_io.cpp           |   6 +-
 interest_rates.cpp         |  16 ++---
 ledger.cpp                 |  13 ++--
 ledger_base.cpp            |  23 ++-----
 ledger_invariant.cpp       |   4 +-
 ledger_text_formats.cpp    |  13 ++--
 ledger_xml_io.cpp          |   2 +-
 ledger_xsl.cpp             |   8 +--
 loads.cpp                  |   6 +-
 main_cgi.cpp               |   2 +-
 mc_enum.tpp                |   4 +-
 mc_enum_types_aux.cpp      |   6 +-
 mec_input.cpp              |   4 +-
 mec_server.cpp             |   4 +-
 menus.xrc                  |  12 ++--
 miscellany.cpp             |   4 +-
 mortality_rates.cpp        |   2 +-
 msw_workarounds.cpp        |   2 +-
 multidimgrid_any.cpp       |  27 +++-----
 multidimgrid_any.hpp       |   6 +-
 multidimgrid_safe.tpp      |  13 +---
 multidimgrid_tools.hpp     |  14 ++--
 multiple_cell_document.cpp |  20 +++---
 mvc_controller.cpp         |  16 ++---
 mvc_controller.tpp         |   6 +-
 mvc_model.cpp              |   2 +-
 path_utility.cpp           |  29 ++-------
 policy_view.cpp            |   4 +-
 premium_tax.cpp            |   8 +--
 product_data.cpp           |   2 +-
 product_editor.cpp         |  15 +----
 progress_meter.cpp         |   8 +--
 progress_meter_cli.cpp     |   7 +-
 rate_table.cpp             | 158 ++++++++++++++++++++++-----------------------
 rate_table_tool.cpp        |  12 ++--
 rounding_rules.cpp         |   4 +-
 rounding_view.cpp          |   4 +-
 sigfpe.cpp                 |   2 +-
 single_cell_document.cpp   |   2 +-
 skeleton.cpp               |  24 ++++---
 solve.cpp                  |   6 +-
 stratified_charges.cpp     |  12 ++--
 system_command_non_wx.cpp  |   4 +-
 system_command_wx.cpp      |  10 +--
 tier_view_editor.cpp       |  22 ++-----
 tier_view_editor.hpp       |   4 +-
 tn_range.tpp               |  18 +++---
 transferor.cpp             |  10 +--
 view_ex.tpp                |  12 +---
 wx_utility.cpp             |  10 +--
 xml_lmi.cpp                |  54 +++++++---------
 xml_serializable.tpp       |  12 ++--
 96 files changed, 510 insertions(+), 665 deletions(-)

diff --git a/accountvalue.cpp b/accountvalue.cpp
index e72e9c5..efc2e8a 100644
--- a/accountvalue.cpp
+++ b/accountvalue.cpp
@@ -76,7 +76,7 @@ namespace
         case mce_monthly:    return 3; // M
         default:
             {
-            fatal_error() << "Case " << a_mode << " not found." << LMI_FLUSH;
+            alarum() << "Case " << a_mode << " not found." << LMI_FLUSH;
             throw "Unreachable--silences a compiler diagnostic.";
             }
         }
@@ -460,7 +460,7 @@ void AccountValue::PerformSpecAmtStrategy()
             break;
         case mce_sa_mep:
             {
-            fatal_error()
+            alarum()
                 << "Modified endowment premium not implemented."
                 << " Payment set to scalar input value."
                 << LMI_FLUSH
@@ -470,7 +470,7 @@ void AccountValue::PerformSpecAmtStrategy()
             break;
         case mce_sa_glp:
             {
-            fatal_error()
+            alarum()
                 << "Guideline level premium not implemented."
                 << " Payment set to scalar input value."
                 << LMI_FLUSH
@@ -480,7 +480,7 @@ void AccountValue::PerformSpecAmtStrategy()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.SpecifiedAmountStrategy[0]
                 << " not found."
@@ -543,7 +543,7 @@ void AccountValue::TxOptionChange()
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
     ActualSpecAmt = round_specamt()(ActualSpecAmt);
@@ -630,7 +630,7 @@ void AccountValue::PerformPmtStrategy(double* a_Pmt)
             break;
         case mce_pmt_mep:
             {
-            fatal_error()
+            alarum()
                 << "Modified endowment premium not implemented."
                 << " Payment set to scalar input value."
                 << LMI_FLUSH
@@ -640,7 +640,7 @@ void AccountValue::PerformPmtStrategy(double* a_Pmt)
             break;
         case mce_pmt_glp:
             {
-            fatal_error()
+            alarum()
                 << "Guideline level premium not implemented."
                 << " Payment set to scalar input value."
                 << LMI_FLUSH
@@ -650,7 +650,7 @@ void AccountValue::PerformPmtStrategy(double* a_Pmt)
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.PaymentStrategy[0]
                 << " not found."
@@ -760,7 +760,7 @@ void AccountValue::TxSetDeathBft(bool)
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
 
@@ -927,7 +927,7 @@ void AccountValue::TxTakeWD()
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
 
diff --git a/actuarial_table.cpp b/actuarial_table.cpp
index 8557b9e..1051f19 100644
--- a/actuarial_table.cpp
+++ b/actuarial_table.cpp
@@ -90,7 +90,7 @@ actuarial_table::actuarial_table(std::string const& filename, 
int table_number)
 {
     if(table_number_ <= 0)
         {
-        fatal_error()
+        alarum()
             << "There is no table number "
             << table_number_
             << " in file '"
@@ -174,7 +174,7 @@ std::vector<double> actuarial_table::values_elaborated
         case e_reenter_never: // Fall through.
         default:
             {
-            fatal_error()
+            alarum()
                 << "Table-lookup method "
                 << method
                 << " is not valid in this context."
@@ -209,7 +209,7 @@ void actuarial_table::find_table()
     fs::ifstream index_ifs(index_path, ios_in_binary());
     if(!index_ifs)
         {
-        fatal_error()
+        alarum()
             << "File '"
             << index_path
             << "' is required but could not be found. Try reinstalling."
@@ -246,7 +246,7 @@ void actuarial_table::find_table()
         index_ifs.read(index_record, index_record_length);
         if(index_record_length != index_ifs.gcount())
             {
-            fatal_error()
+            alarum()
                 << "Table "
                 << table_number_
                 << " in file '"
@@ -263,7 +263,7 @@ void actuarial_table::find_table()
 
     if(std::streampos(-1) == table_offset_)
         {
-        fatal_error()
+        alarum()
             << "Table "
             << table_number_
             << " in file '"
@@ -306,7 +306,7 @@ void actuarial_table::parse_table()
     fs::ifstream data_ifs(data_path, ios_in_binary());
     if(!data_ifs)
         {
-        fatal_error()
+        alarum()
             << "File '"
             << data_path
             << "' is required but could not be found. Try reinstalling."
@@ -555,7 +555,7 @@ std::vector<double> actuarial_table::specific_values
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Table type '"
                 << table_type_
                 << "' not recognized: must be one of 'A', 'D', or 'S'."
diff --git a/alert.cpp b/alert.cpp
index 2a48c8f..10729b3 100644
--- a/alert.cpp
+++ b/alert.cpp
@@ -40,7 +40,7 @@ typedef void (*alert_function_pointer)(std::string const&);
 alert_function_pointer status_alert_function         = nullptr;
 alert_function_pointer warning_alert_function        = nullptr;
 alert_function_pointer hobsons_choice_alert_function = nullptr;
-alert_function_pointer fatal_error_alert_function    = nullptr;
+alert_function_pointer alarum_alert_function         = nullptr;
 
 typedef void (*message_function_pointer)(char const*);
 message_function_pointer safe_message_alert_function = nullptr;
@@ -51,7 +51,7 @@ inline bool all_function_pointers_have_been_set()
             nullptr != status_alert_function
         &&  nullptr != warning_alert_function
         &&  nullptr != hobsons_choice_alert_function
-        &&  nullptr != fatal_error_alert_function
+        &&  nullptr != alarum_alert_function
         &&  nullptr != safe_message_alert_function
         ;
 }
@@ -62,7 +62,7 @@ inline bool any_function_pointer_has_been_set()
             nullptr != status_alert_function
         ||  nullptr != warning_alert_function
         ||  nullptr != hobsons_choice_alert_function
-        ||  nullptr != fatal_error_alert_function
+        ||  nullptr != alarum_alert_function
         ||  nullptr != safe_message_alert_function
         ;
 }
@@ -88,7 +88,7 @@ bool set_alert_functions
     (void(*status_alert_function_pointer        )(std::string const&)
     ,void(*warning_alert_function_pointer       )(std::string const&)
     ,void(*hobsons_choice_alert_function_pointer)(std::string const&)
-    ,void(*fatal_error_alert_function_pointer   )(std::string const&)
+    ,void(*alarum_alert_function_pointer        )(std::string const&)
     ,void(*safe_message_alert_function_pointer  )(char const*)
     )
 {
@@ -101,7 +101,7 @@ bool set_alert_functions
     status_alert_function         = status_alert_function_pointer        ;
     warning_alert_function        = warning_alert_function_pointer       ;
     hobsons_choice_alert_function = hobsons_choice_alert_function_pointer;
-    fatal_error_alert_function    = fatal_error_alert_function_pointer   ;
+    alarum_alert_function         = alarum_alert_function_pointer        ;
     safe_message_alert_function   = safe_message_alert_function_pointer  ;
     return true;
 }
@@ -175,12 +175,12 @@ class hobsons_choice_buf
         }
 };
 
-class fatal_error_buf
+class alarum_buf
     :public alert_buf
 {
     void raise_alert() override
         {
-        fatal_error_alert_function(alert_string());
+        alarum_alert_function(alert_string());
         }
 };
 
@@ -216,9 +216,9 @@ std::ostream& hobsons_choice()
     return alert_stream<hobsons_choice_buf>();
 }
 
-std::ostream& fatal_error()
+std::ostream& alarum()
 {
-    return alert_stream<fatal_error_buf>();
+    return alert_stream<alarum_buf>();
 }
 
 void safely_show_message(char const* message)
@@ -260,9 +260,9 @@ void test_hobsons_choice()
     hobsons_choice() << "Test hobsons_choice()" << LMI_FLUSH;
 }
 
-void test_fatal_error()
+void test_alarum()
 {
-    fatal_error()    << "Test fatal_error()"    << LMI_FLUSH;
+    alarum()         << "Test alarum()"         << LMI_FLUSH;
 }
 
 void test_standard_exception()
diff --git a/alert.hpp b/alert.hpp
index 718df94..c59da7f 100644
--- a/alert.hpp
+++ b/alert.hpp
@@ -54,7 +54,7 @@
 /// the user's attention: the program can continue, but not in exactly
 /// the way the user wanted, so resumption semantics are appropriate.
 /// All interfaces must display a message (e.g., a GUI would typically
-/// use a messagebox) but, unlike fatal_error, not routinely throw an
+/// use a messagebox) but, unlike alarum(), not routinely throw an
 /// exception (unless due to internal error).
 ///
 /// hobsons_choice: Serious runtime problems that users may be allowed
@@ -66,7 +66,7 @@
 /// used only for regression testing might print a message and attempt
 /// to continue.
 ///
-/// fatal_error: Dire runtime problems that prevent the system from
+/// alarum: Dire runtime problems that prevent the system from
 /// performing a requested action in any reasonable manner, and that
 /// therefore call for resumption semantics. All interfaces must show
 /// a message and throw an exception when the stream is flushed. A GUI
@@ -87,15 +87,15 @@
 ///
 /// Usage notes.
 ///
-/// The 'lmi' project is gradually striving to favor fatal_error()
-/// over warning() and hobsons_choice(). For temporary debugging code,
+/// The 'lmi' project is gradually striving to favor alarum() over
+/// warning() and hobsons_choice(). For temporary debugging code,
 /// warning() is often useful, but production code should generally
 /// avoid warning() and especially hobsons_choice(). Already, option
 /// 'offer_hobsons_choice' in 'configurable_settings.?pp', if set as
 /// recommended, removes the user choice from hobsons_choice().
 ///
 /// Sometimes gcc warns of a missing return statement after the stream
-/// returned by fatal_error() is flushed: an exception is obligatorily
+/// returned by alarum() is flushed: an exception is obligatorily
 /// thrown, but it is difficult for a compiler to discern that. When
 /// (and only when) gcc issues such a warning, add exactly this line:
 ///   throw "Unreachable--silences a compiler diagnostic.";
@@ -119,8 +119,8 @@
 /// The output destination could easily be expressed as a manipulator:
 ///   single_ostream << "error" << some_variable << messagebox;
 /// That might be a slightly simpler design. And it is intended that an
-/// exception be thrown for fatal errors at least, which seems more
-/// like an independent action than a consequence of flushing a stream.
+/// exception be thrown for alarum() at least, which seems more like
+/// an independent action than a consequence of flushing a stream.
 /// But following the std::cerr paradigm is the least surprising
 /// approach, and it seems natural enough to emit the contents of the
 /// buffer when std::flush is called.
@@ -160,7 +160,7 @@ namespace alert_classes{} // doxygen workaround.
 std::ostream& LMI_SO status();
 std::ostream& LMI_SO warning();
 std::ostream& LMI_SO hobsons_choice();
-std::ostream& LMI_SO fatal_error();
+std::ostream& LMI_SO alarum();
 
 void LMI_SO safely_show_message(char const*);
 void LMI_SO safely_show_message(std::string const&);
@@ -174,7 +174,7 @@ void LMI_SO safely_show_message(std::string const&);
 void status_alert         (std::string const&);
 void warning_alert        (std::string const&);
 void hobsons_choice_alert (std::string const&);
-void fatal_error_alert    (std::string const&);
+void alarum_alert         (std::string const&);
 
 /// Implement this function for each platform, in a manner that should
 /// always work safely and immediately. For instance, for the wx GUI
@@ -200,7 +200,7 @@ bool LMI_SO set_alert_functions
     (void(*status_alert_function_pointer        )(std::string const&)
     ,void(*warning_alert_function_pointer       )(std::string const&)
     ,void(*hobsons_choice_alert_function_pointer)(std::string const&)
-    ,void(*fatal_error_alert_function_pointer   )(std::string const&)
+    ,void(*alarum_alert_function_pointer        )(std::string const&)
     ,void(*safe_message_alert_function_pointer  )(char const*)
     );
 
@@ -213,7 +213,7 @@ bool LMI_SO set_alert_functions
 /// of other code, failure semantics are more appropriate, because
 /// such tests should not require manual intervention; therefore, the
 /// implementation provided for a command-line interface writes to
-/// stderr and signals a fatal error. A server application probably
+/// stderr and signals an exception. A server application probably
 /// should fail and write a message in a log file.
 
 std::string const& LMI_SO hobsons_prompt();
@@ -242,7 +242,7 @@ class hobsons_choice_exception
 void LMI_SO test_status();
 void LMI_SO test_warning();
 void LMI_SO test_hobsons_choice();
-void LMI_SO test_fatal_error();
+void LMI_SO test_alarum();
 void LMI_SO test_standard_exception();
 void LMI_SO test_arbitrary_exception();
 void LMI_SO test_catastrophe_report();
diff --git a/alert_cgi.cpp b/alert_cgi.cpp
index 38d5230..b105ec0 100644
--- a/alert_cgi.cpp
+++ b/alert_cgi.cpp
@@ -32,7 +32,7 @@ volatile bool ensure_setup = set_alert_functions
     (status_alert
     ,warning_alert
     ,hobsons_choice_alert
-    ,fatal_error_alert
+    ,alarum_alert
     ,safe_message_alert
     );
 } // Unnamed namespace.
@@ -57,7 +57,7 @@ void hobsons_choice_alert(std::string const& s)
     throw std::runtime_error(s);
 }
 
-void fatal_error_alert(std::string const& s)
+void alarum_alert(std::string const& s)
 {
     throw std::runtime_error(s);
 }
diff --git a/alert_cli.cpp b/alert_cli.cpp
index 8db113e..39c4076 100644
--- a/alert_cli.cpp
+++ b/alert_cli.cpp
@@ -37,7 +37,7 @@ volatile bool ensure_setup = set_alert_functions
     (status_alert
     ,warning_alert
     ,hobsons_choice_alert
-    ,fatal_error_alert
+    ,alarum_alert
     ,safe_message_alert
     );
 
@@ -96,7 +96,7 @@ void hobsons_choice_alert(std::string const& s)
         }
 }
 
-void fatal_error_alert(std::string const& s)
+void alarum_alert(std::string const& s)
 {
     throw std::runtime_error(s);
 }
diff --git a/alert_test.cpp b/alert_test.cpp
index 8647621..1e72d7d 100644
--- a/alert_test.cpp
+++ b/alert_test.cpp
@@ -66,17 +66,17 @@ int test_main(int, char*[])
     warning() << "File and line where this diagnostic arose:";
     warning() << LMI_FLUSH;
 
-    // Run this 'fatal_error' test twice in order to ensure that the
-    // stream state is cleared after an exception is thrown; if it is
-    // not, then getting a reference to the stream again, e.g., by
-    // calling fatal_error(), fails with an exception inside the
-    // standard library, probably in std::ios_base::clear().
+    // Run this 'alarum' test twice in order to ensure that the stream
+    // state is cleared after an exception is thrown; if it is not,
+    // then getting a reference to the stream again, e.g., by calling
+    // alarum(), fails with an exception inside the standard library,
+    // probably in std::ios_base::clear().
 
-    std::string s("First simulated fatal error.");
-    BOOST_TEST_THROW(fatal_error() << s << std::flush, std::runtime_error, s);
+    std::string s("First simulated alarum.");
+    BOOST_TEST_THROW(alarum() << s << std::flush, std::runtime_error, s);
 
-    s = "Second simulated fatal error.";
-    BOOST_TEST_THROW(fatal_error() << s << std::flush, std::runtime_error, s);
+    s = "Second simulated alarum.";
+    BOOST_TEST_THROW(alarum() << s << std::flush, std::runtime_error, s);
 
 #if defined __GLIBCPP__ && __GLIBCPP__==20030426
     std::cout
diff --git a/alert_wx.cpp b/alert_wx.cpp
index 9d3b29f..2eabf58 100644
--- a/alert_wx.cpp
+++ b/alert_wx.cpp
@@ -44,7 +44,7 @@ volatile bool ensure_setup = set_alert_functions
     (status_alert
     ,warning_alert
     ,hobsons_choice_alert
-    ,fatal_error_alert
+    ,alarum_alert
     ,safe_message_alert
     );
 } // Unnamed namespace.
@@ -115,7 +115,7 @@ void hobsons_choice_alert(std::string const& s)
         }
 }
 
-void fatal_error_alert(std::string const& s)
+void alarum_alert(std::string const& s)
 {
     throw std::runtime_error(s);
 }
diff --git a/authenticity.cpp b/authenticity.cpp
index 7d49bc0..bf951ce 100644
--- a/authenticity.cpp
+++ b/authenticity.cpp
@@ -70,7 +70,7 @@ Authenticity& Authenticity::Instance()
     catch(...)
         {
         report_exception();
-        fatal_error() << "Instantiation failed." << LMI_FLUSH;
+        alarum() << "Instantiation failed." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/basicvalues.cpp b/basicvalues.cpp
index a06c867..368117e 100644
--- a/basicvalues.cpp
+++ b/basicvalues.cpp
@@ -196,7 +196,7 @@ double BasicValues::GetModalTgtPrem
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << a_mode
                 << " not found."
@@ -280,7 +280,7 @@ double BasicValues::GetModalTgtSpecAmt
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << a_mode
                 << " not found."
diff --git a/calendar_date.cpp b/calendar_date.cpp
index 07ec368..2b95304 100644
--- a/calendar_date.cpp
+++ b/calendar_date.cpp
@@ -69,7 +69,7 @@ namespace
             };
         if(!(0 < month && month < 13))
             {
-            fatal_error()
+            alarum()
                 << "Month "
                 << month
                 << " is outside the range [1, 12]."
@@ -149,7 +149,7 @@ namespace
             ||  original_day   != day
             )
             {
-            fatal_error()
+            alarum()
                 << "Date "
                 << format_yyyy_mm_dd_with_hyphens
                     (original_year
@@ -491,7 +491,7 @@ int attained_age
 {
     if(as_of_date < birthdate)
         {
-        fatal_error()
+        alarum()
             << "As-of date ("
             << as_of_date.str()
             << ") precedes birthdate ("
@@ -523,7 +523,7 @@ std::pair<int,int> years_and_months_since
 {
     if(other_date < base_date)
         {
-        fatal_error()
+        alarum()
             << "Second date ("
             << other_date.str()
             << ") precedes first date ("
@@ -684,7 +684,7 @@ class birthdate_limit
             }
         else
             {
-            fatal_error() << "Unexpected case." << LMI_FLUSH;
+            alarum() << "Unexpected case." << LMI_FLUSH;
             }
         }
 
@@ -749,7 +749,7 @@ std::string month_name(int month)
 {
     if(!(0 < month && month < 13))
         {
-        fatal_error()
+        alarum()
             << "Month "
             << month
             << " is outside the range [1, 12]."
diff --git a/calendar_date_test.cpp b/calendar_date_test.cpp
index 7488196..02d5dd6 100644
--- a/calendar_date_test.cpp
+++ b/calendar_date_test.cpp
@@ -146,7 +146,7 @@ void CalendarDateTest::TestAlgorithm199Bounds()
             ||  !(0 < c.day()   && c.day()   < 32)
             )
             {
-            fatal_error()
+            alarum()
                 << "Algorithm 199 failed for jdn "
                 << j
                 << ", which it would translate to gregorian date '"
diff --git a/ce_product_name.cpp b/ce_product_name.cpp
index 09f7466..5f99602 100644
--- a/ce_product_name.cpp
+++ b/ce_product_name.cpp
@@ -54,7 +54,7 @@ std::vector<std::string> fetch_product_names()
 
     if(names.empty())
         {
-        fatal_error()
+        alarum()
             << "Data directory '"
             << path
             << "' contains no product files."
@@ -132,7 +132,7 @@ std::size_t ce_product_name::ordinal(std::string const& s)
         ;
     if(v == product_names().size())
         {
-        fatal_error()
+        alarum()
             << "Value '"
             << s
             << "' invalid for type '"
diff --git a/ce_skin_name.cpp b/ce_skin_name.cpp
index c2c6766..9a4d8ab 100644
--- a/ce_skin_name.cpp
+++ b/ce_skin_name.cpp
@@ -60,7 +60,7 @@ std::vector<std::string> fetch_skin_names()
 
     if(names.empty())
         {
-        fatal_error()
+        alarum()
             << "Data directory '"
             << path
             << "' contains no skin files."
@@ -129,7 +129,7 @@ std::size_t ce_skin_name::ordinal(std::string const& s)
         ;
     if(v == skin_names().size())
         {
-        fatal_error()
+        alarum()
             << "Value '"
             << s
             << "' invalid for type '"
diff --git a/census_view.cpp b/census_view.cpp
index 98e0235..e0e2780 100644
--- a/census_view.cpp
+++ b/census_view.cpp
@@ -1082,7 +1082,7 @@ void CensusView::update_class_names()
             // It should not be possible for no cell to be found in the class.
             if(!found)
                 {
-                fatal_error()
+                alarum()
                     << "Cannot find any cell in class "
                     << "'" << *n << "'."
                     << LMI_FLUSH
@@ -1586,7 +1586,7 @@ void CensusView::UponRunCaseToGroupRoster(wxCommandEvent&)
             break;
         default:
             {
-            fatal_error() << "Case " << selection << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << selection << " not found." << LMI_FLUSH;
             }
         }
 }
@@ -1652,7 +1652,7 @@ void CensusView::UponPasteCensus(wxCommandEvent&)
     bool const age_pasted = contains(headers, "IssueAge");
     if(dob_pasted && age_pasted)
         {
-        fatal_error()
+        alarum()
             << "Cannot paste both 'DateOfBirth' and 'IssueAge'."
             << LMI_FLUSH
             ;
@@ -1697,12 +1697,12 @@ void CensusView::UponPasteCensus(wxCommandEvent&)
                     << "Last valid value, if any: " << values.back()
                     << LMI_FLUSH
                     ;
-// TODO ?? It would be better to use fatal_error() instead of
-// warning() followed by fatal_error() with a short string, but
+// TODO ?? It would be better to use alarum() instead of
+// warning() followed by alarum() with a short string, but
 // apparently that can segfault with very long strings. Is there
 // a limit on exception size that should be tested here? See:
 //   http://savannah.nongnu.org/bugs/?20240
-                fatal_error() << "Invalid input." << LMI_FLUSH;
+                alarum() << "Invalid input." << LMI_FLUSH;
                 }
 #endif // 0
             values.push_back(token);
@@ -1710,7 +1710,7 @@ void CensusView::UponPasteCensus(wxCommandEvent&)
 
         if(values.size() != headers.size())
             {
-            fatal_error()
+            alarum()
                 << "Line #" << current_line << ": "
                 << "  (" << line << ") "
                 << "should have one value per column. "
@@ -1740,7 +1740,7 @@ void CensusView::UponPasteCensus(wxCommandEvent&)
                     }
                 else
                     {
-                    fatal_error()
+                    alarum()
                         << "Invalid date " << values[j]
                         << " for '" << headers[j] << "'"
                         << " on line " << current_line << "."
diff --git a/configurable_settings.cpp b/configurable_settings.cpp
index dac8805..6bc05cb 100644
--- a/configurable_settings.cpp
+++ b/configurable_settings.cpp
@@ -94,7 +94,7 @@ fs::path const& configuration_filepath()
         filename = AddDataDir(configuration_filename());
         if(0 != access(filename.c_str(), R_OK))
             {
-            fatal_error()
+            alarum()
                 << "No readable file '"
                 << configuration_filename()
                 << "' exists."
@@ -185,7 +185,7 @@ configurable_settings& configurable_settings::instance()
     catch(...)
         {
         report_exception();
-        fatal_error() << "Instantiation failed." << LMI_FLUSH;
+        alarum() << "Instantiation failed." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/custom_io_0.cpp b/custom_io_0.cpp
index fb50b14..989bd60 100644
--- a/custom_io_0.cpp
+++ b/custom_io_0.cpp
@@ -206,7 +206,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
         ;
     if(0 != access(actual_filename.c_str(), F_OK))
         {
-        fatal_error()
+        alarum()
             << "File '"
             << actual_filename
             << "' is required but could not be found."
@@ -251,7 +251,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "ApplicantGender is '"
             << gender
             << "', but it must be 'F', 'M', or 'U'."
@@ -274,7 +274,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "ApplicantTobacco is '"
             << tobacco
             << "', but it must be 'Y', 'N', or 'U'."
@@ -292,7 +292,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
 
     if("Standard" != z["UnderwritingClass"].str())
         {
-        fatal_error()
+        alarum()
             << "Internal error: not initialized to standard rate class."
             << LMI_FLUSH
             ;
@@ -318,7 +318,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "ProductOption is '"
             << undw
             << "', but it must be 'P', 'F', 'S', or 'G'."
@@ -341,7 +341,7 @@ bool custom_io_0_read(Input& z, std::string const& filename)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "DeathBenefitOption is '"
             << dbopt
             << "', but it must be 'L', 'I', or 'ROP'."
@@ -494,7 +494,7 @@ void custom_io_0_write(Ledger const& ledger_values, 
std::string const& filename)
         );
     if(!os.good())
         {
-        fatal_error()
+        alarum()
             << "File '"
             << actual_filename
             << "' could not be opened for writing."
@@ -541,7 +541,7 @@ void custom_io_0_write(Ledger const& ledger_values, 
std::string const& filename)
         }
     if(!os.good())
         {
-        fatal_error() << "Error writing output file." << LMI_FLUSH;
+        alarum() << "Error writing output file." << LMI_FLUSH;
         }
 }
 
diff --git a/custom_io_1.cpp b/custom_io_1.cpp
index 17c845e..b7986f0 100644
--- a/custom_io_1.cpp
+++ b/custom_io_1.cpp
@@ -82,7 +82,7 @@ bool custom_io_1_read(Input& z, std::string const& filename)
         ;
     if(0 != access(actual_filename.c_str(), F_OK))
         {
-        fatal_error()
+        alarum()
             << "File '"
             << actual_filename
             << "' is required but could not be found."
@@ -363,7 +363,7 @@ void custom_io_1_write(Ledger const& ledger_values, 
std::string const& filename)
         );
     if(!os.good())
         {
-        fatal_error()
+        alarum()
             << "File '"
             << actual_filename
             << "' could not be opened for writing."
@@ -410,7 +410,7 @@ void custom_io_1_write(Ledger const& ledger_values, 
std::string const& filename)
         }
     if(!os.good())
         {
-        fatal_error() << "Error writing output file." << LMI_FLUSH;
+        alarum() << "Error writing output file." << LMI_FLUSH;
         }
 }
 
diff --git a/database_view_editor.cpp b/database_view_editor.cpp
index e5224ec..4b3cb04 100644
--- a/database_view_editor.cpp
+++ b/database_view_editor.cpp
@@ -125,11 +125,11 @@ bool DatabaseTableAdapter::DoApplyAxisAdjustment
             static_cast<DatabaseDurationAxis&>(axis);
         if(duration_axis.GetMinValue() != 0)
             {
-            fatal_error() << "Duration must start at 0." << LMI_FLUSH;
+            alarum() << "Duration must start at 0." << LMI_FLUSH;
             }
         if(duration_axis.GetMaxValue() < 0)
             {
-            fatal_error()
+            alarum()
                 << "Duration must have at least one value."
                 << LMI_FLUSH
                 ;
diff --git a/dbdict.cpp b/dbdict.cpp
index bfca4cb..2323fe0 100644
--- a/dbdict.cpp
+++ b/dbdict.cpp
@@ -68,7 +68,7 @@ template<> struct xml_io<database_entity>
 
 template<> std::string value_cast<std::string>(database_entity const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
@@ -80,7 +80,7 @@ template<> std::string 
value_cast<std::string>(database_entity const&)
 
 template<> database_entity value_cast<database_entity>(std::string const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
diff --git a/dbvalue.cpp b/dbvalue.cpp
index 23ad411..35492ed 100644
--- a/dbvalue.cpp
+++ b/dbvalue.cpp
@@ -265,7 +265,7 @@ double& database_entity::operator[](std::vector<int> const& 
index)
     if(static_cast<int>(data_values_.size()) <= z)
         {
         z = 0;
-        fatal_error()
+        alarum()
             << "Trying to index database item '"
             << GetDBNames()[key_].ShortName
             << "' past end of data."
@@ -295,7 +295,7 @@ double const* database_entity::operator[](database_index 
const& idx) const
     if(static_cast<int>(data_values_.size()) <= z)
         {
         z = 0;
-        fatal_error()
+        alarum()
             << "Trying to index database item '"
             << GetDBNames()[key_].ShortName
             << "' past end of data."
@@ -383,7 +383,7 @@ void database_entity::assert_invariants() const
         {
         if(*ai != 1 && *ai != *mi && *ai != axis_lengths_.back())
             {
-            fatal_error()
+            alarum()
                 << "Database item '"
                 << GetDBNames()[key_].ShortName
                 << "' has invalid length "
@@ -400,7 +400,7 @@ void database_entity::assert_invariants() const
 
     if(max_dims.back() < axis_lengths_.back())
             {
-            fatal_error()
+            alarum()
                 << "Database item '"
                 << GetDBNames()[key_].ShortName
                 << "' has invalid duration."
@@ -420,7 +420,7 @@ int database_entity::getndata() const
     catch(...)
         {
         report_exception();
-        fatal_error()
+        alarum()
             << "Database item '"
             << GetDBNames()[key_].ShortName
             << "' has invalid dimensions."
@@ -445,7 +445,7 @@ int database_entity::getndata(std::vector<int> const& z)
 
     if(MaxPossibleElements < n)
         {
-        fatal_error()
+        alarum()
             << "There are " << n
             << " data, but at most " << MaxPossibleElements
             << " are permitted."
@@ -455,7 +455,7 @@ int database_entity::getndata(std::vector<int> const& z)
 
     if(n <= 0)
         {
-        fatal_error() << "Number of data must exceed zero." << LMI_FLUSH;
+        alarum() << "Number of data must exceed zero." << LMI_FLUSH;
         }
 
     LMI_ASSERT(MaxPossibleElements <= std::numeric_limits<int>::max());
diff --git a/file_command_cgi.cpp b/file_command_cgi.cpp
index ef11e9e..0c258f9 100644
--- a/file_command_cgi.cpp
+++ b/file_command_cgi.cpp
@@ -32,7 +32,7 @@ void concrete_file_command
     ,std::string const&
     )
 {
-    fatal_error()
+    alarum()
         << "Class 'file_command' not implemented for cgi-bin interface."
         << LMI_FLUSH
         ;
diff --git a/file_command_cli.cpp b/file_command_cli.cpp
index 3a13b22..4d1f19a 100644
--- a/file_command_cli.cpp
+++ b/file_command_cli.cpp
@@ -32,7 +32,7 @@ void concrete_file_command
     ,std::string const&
     )
 {
-    fatal_error()
+    alarum()
         << "Class 'file_command' not implemented for command-line interface."
         << LMI_FLUSH
         ;
diff --git a/file_command_wx.cpp b/file_command_wx.cpp
index 83a3f3c..b7d1842 100644
--- a/file_command_wx.cpp
+++ b/file_command_wx.cpp
@@ -55,12 +55,7 @@ void concrete_file_command
 
     if(!ft)
         {
-        fatal_error()
-            << "File type '"
-            << extension
-            << "' unknown."
-            << LMI_FLUSH
-            ;
+        alarum() << "File type '" << extension << "' unknown." << LMI_FLUSH;
         }
 
     wxString cmd;
@@ -87,18 +82,13 @@ void concrete_file_command
         }
     else
         {
-        fatal_error()
-            << "Action '"
-            << action
-            << "' unrecognized."
-            << LMI_FLUSH
-            ;
+        alarum() << "Action '" << action << "' unrecognized." << LMI_FLUSH;
         return;
         }
 
     if(!okay)
         {
-        fatal_error()
+        alarum()
             << "Unable to determine command to '"
             << action
             << "' file '"
@@ -110,7 +100,7 @@ void concrete_file_command
     okay = wxExecute(cmd);
     if(!okay)
         {
-        fatal_error()
+        alarum()
             << "Unable to '"
             << action
             << "' file '"
diff --git a/fund_data.cpp b/fund_data.cpp
index 3b8ee52..d96bab8 100644
--- a/fund_data.cpp
+++ b/fund_data.cpp
@@ -113,7 +113,7 @@ void FundData::Read(std::string const& a_Filename)
 {
     if(access(a_Filename.c_str(), R_OK))
         {
-        fatal_error()
+        alarum()
             << "File '"
             << a_Filename
             << "' is required but could not be found. Try reinstalling."
diff --git a/global_settings.cpp b/global_settings.cpp
index 68f5db2..b0bc0dc 100644
--- a/global_settings.cpp
+++ b/global_settings.cpp
@@ -65,7 +65,7 @@ global_settings& global_settings::instance()
     catch(...)
         {
         report_exception();
-        fatal_error() << "Instantiation failed." << LMI_FLUSH;
+        alarum() << "Instantiation failed." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/gpt_input.cpp b/gpt_input.cpp
index 3f7f1f7..57142b9 100644
--- a/gpt_input.cpp
+++ b/gpt_input.cpp
@@ -358,7 +358,7 @@ void gpt_input::DoHarmonize()
         }
     else
         {
-        fatal_error()
+        alarum()
             << "No option selected for definition of life insurance."
             << LMI_FLUSH
             ;
@@ -592,7 +592,7 @@ std::vector<std::string> 
gpt_input::RealizeAllSequenceInput(bool report_errors)
                 }
             if(diagnostics_present)
                 {
-                fatal_error()
+                alarum()
                     << "Input validation problems:\n"
                     << oss.str()
                     << LMI_FLUSH
diff --git a/gpt_server.cpp b/gpt_server.cpp
index 8e3156b..7a8cf66 100644
--- a/gpt_server.cpp
+++ b/gpt_server.cpp
@@ -308,7 +308,7 @@ gpt_state test_one_days_gpt_transactions
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Unknown modal premium type " << target_premium_type << '.'
             << LMI_FLUSH
             ;
@@ -532,7 +532,7 @@ bool gpt_server::operator()(fs::path const& file_path)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "File '"
             << file_path
             << "': extension '"
diff --git a/group_quote_pdf_gen_wx.cpp b/group_quote_pdf_gen_wx.cpp
index bb37e52..7885fc5 100644
--- a/group_quote_pdf_gen_wx.cpp
+++ b/group_quote_pdf_gen_wx.cpp
@@ -373,7 +373,7 @@ void output_image
             break;
         default:
             {
-            fatal_error() << "Case " << output_mode << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << output_mode << " not found." << LMI_FLUSH;
             }
         }
 
@@ -419,7 +419,7 @@ int output_html
             break;
         default:
             {
-            fatal_error() << "Case " << output_mode << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << output_mode << " not found." << LMI_FLUSH;
             }
         }
 
@@ -624,7 +624,7 @@ void assert_nonblank(std::string const& value, std::string 
const& name)
 {
     if(std::string::npos == value.find_first_not_of(" \f\n\r\t\v"))
         {
-        fatal_error() << name << " must not be blank." << LMI_FLUSH;
+        alarum() << name << " must not be blank." << LMI_FLUSH;
         }
 }
 
@@ -746,7 +746,7 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger const& 
ledger)
 {
     if(0 == ledger.GetCurrFull().LapseYear)
         {
-        fatal_error() << "Lapsed during first year." << LMI_FLUSH;
+        alarum() << "Lapsed during first year." << LMI_FLUSH;
         }
 
     LedgerInvariant const& invar = ledger.GetLedgerInvariant();
@@ -759,7 +759,7 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger const& 
ledger)
         {
         if(invar.GroupIndivSelection != individual_selection_)
             {
-            fatal_error()
+            alarum()
                 << "Group quotes cannot mix mandatory and voluntary on the 
same plan."
                 << LMI_FLUSH
                 ;
@@ -866,12 +866,12 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger 
const& ledger)
                 break;
             case e_col_max:
                 {
-                fatal_error() << "Unreachable." << LMI_FLUSH;
+                alarum() << "Unreachable." << LMI_FLUSH;
                 }
                 break;
             default:
                 {
-                fatal_error() << "Case " << col << " not found." << LMI_FLUSH;
+                alarum() << "Case " << col << " not found." << LMI_FLUSH;
                 }
             }
         }
@@ -1001,12 +1001,12 @@ void 
group_quote_pdf_generator_wx::do_generate_pdf(wxPdfDC& pdf_dc)
                 break;
             case e_col_max:
                 {
-                fatal_error() << "Unreachable." << LMI_FLUSH;
+                alarum() << "Unreachable." << LMI_FLUSH;
                 }
                 break;
             default:
                 {
-                fatal_error() << "Case " << col << " not found." << LMI_FLUSH;
+                alarum() << "Case " << col << " not found." << LMI_FLUSH;
                 }
             }
 
@@ -1389,7 +1389,7 @@ void group_quote_pdf_generator_wx::output_aggregate_values
                 break;
             default:
                 {
-                fatal_error() << "Case " << col << " not found." << LMI_FLUSH;
+                alarum() << "Case " << col << " not found." << LMI_FLUSH;
                 }
             }
 
diff --git a/group_values.cpp b/group_values.cpp
index 144ae39..bfab05f 100644
--- a/group_values.cpp
+++ b/group_values.cpp
@@ -286,7 +286,7 @@ census_run_result run_census_in_parallel::operator()
                 ||  first_cell_inforce_month != av->yare_input_.InforceMonth
                 )
                 {
-                fatal_error()
+                alarum()
                     << "Running census by month untested for inforce"
                     << " with inforce duration varying across cells."
                     << LMI_FLUSH
@@ -295,7 +295,7 @@ census_run_result run_census_in_parallel::operator()
 
             if(mce_solve_none != av->yare_input_.SolveType)
                 {
-                fatal_error()
+                alarum()
                     << "Running census by month: solves not permitted."
                     << LMI_FLUSH
                     ;
@@ -315,7 +315,7 @@ census_run_result run_census_in_parallel::operator()
     if(cell_values.empty())
         {
         // Make sure it's safe to dereference cell_values[0] later.
-        fatal_error()
+        alarum()
             << "No cell with any lives was included in the composite."
             << LMI_FLUSH
             ;
@@ -578,7 +578,7 @@ census_run_result run_census_in_parallel::operator()
                         )
                     )
                     {
-                    fatal_error()
+                    alarum()
                         << "\nExperience-rating reserve discrepancy in year "
                         << year
                         << ": "
@@ -723,7 +723,7 @@ census_run_result run_census::operator()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << order
                 << " not found."
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 0599b31..95169b2 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -243,7 +243,7 @@ double AccountValue::RunOneBasis(mcenum_run_basis a_Basis)
         && mce_run_gen_mdpt_sep_full == a_Basis
         )
         {
-        fatal_error()
+        alarum()
             << "Midpoint basis defined only for illustration-reg ledger."
             << LMI_FLUSH
             ;
@@ -611,7 +611,7 @@ void AccountValue::SetInitialValues()
 
     if(!Database_->Query(DB_AllowGenAcct) && 0.0 != GenAcctPaymentAllocation)
         {
-        fatal_error()
+        alarum()
             << "No general account is allowed for this product, but "
             << GenAcctPaymentAllocation
             << " is allocated to the general account."
@@ -621,7 +621,7 @@ void AccountValue::SetInitialValues()
 
     if(!Database_->Query(DB_AllowSepAcct) && 0.0 != SepAcctPaymentAllocation)
         {
-        fatal_error()
+        alarum()
             << "No separate account is allowed for this product, but "
             << SepAcctPaymentAllocation
             << " is allocated to the separate account."
@@ -800,7 +800,7 @@ double AccountValue::IncrementBOM
         ||  daily_interest_accounting && !(28 <= days_in_policy_month && 
days_in_policy_month <= 31)
         )
         {
-        fatal_error()
+        alarum()
             << "Expected year = "  << Year
             << "; actual year is  " << year << ".\n"
             << "Expected month = " << Month
@@ -1864,7 +1864,7 @@ void AccountValue::CoordinateCounters()
 //   eleventh monthiversary 2001-02-28 (not the twenty-ninth)
         if(days_in_policy_month !=  current_monthiversary.days_in_month())
             {
-            fatal_error()
+            alarum()
                 << Year << " Year; " << Month << " Month\n"
                 << current_monthiversary.year() << '-'
                 << current_monthiversary.month() << '-'
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index 52d89ff..84713f2 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -297,7 +297,7 @@ void AccountValue::process_payment(double payment)
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << ee_premium_allocation_method
                 << "' not found."
@@ -319,7 +319,7 @@ void AccountValue::process_payment(double payment)
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << er_premium_allocation_method
                 << "' not found."
@@ -362,7 +362,7 @@ void AccountValue::IncrementAVPreferentially
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << preferred_account
                 << "' not found."
@@ -391,7 +391,7 @@ void AccountValue::process_deduction(double decrement)
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << deduction_method
                 << "' not found."
@@ -419,7 +419,7 @@ void AccountValue::process_distribution(double decrement)
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << distribution_method
                 << "' not found."
@@ -524,7 +524,7 @@ void AccountValue::DecrementAVProgressively
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << preferred_account
                 << "' not found."
@@ -758,7 +758,7 @@ void AccountValue::ChangeSpecAmtBy(double delta)
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case "
                     << yare_input_.TermAdjustmentMethod
                     << " not found."
@@ -926,7 +926,7 @@ void AccountValue::TxOptionChange()
 
     if(!AllowChangeToDBO2 && mce_option2 == YearsDBOpt)
         {
-        fatal_error()
+        alarum()
             << "Change to increasing death benefit option"
             << " not allowed on this policy form."
             << LMI_FLUSH
@@ -962,7 +962,7 @@ void AccountValue::TxOptionChange()
                     }
                 else
                     {
-                    fatal_error() << "Unknown death benefit option." << 
LMI_FLUSH;
+                    alarum() << "Unknown death benefit option." << LMI_FLUSH;
                     }
                 }
             else
@@ -995,7 +995,7 @@ void AccountValue::TxOptionChange()
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
 }
@@ -1055,7 +1055,7 @@ void AccountValue::TxSpecAmtChange()
         &&  ActualSpecAmt < YearsSpecAmt
         )
         {
-        fatal_error()
+        alarum()
             << "Specified-amount increases not allowed on this policy form."
             << LMI_FLUSH
             ;
@@ -1068,7 +1068,7 @@ void AccountValue::TxSpecAmtChange()
         &&  ActualSpecAmt < YearsSpecAmt
         )
         {
-        fatal_error()
+        alarum()
             << "Cannot increase specified amount after age "
             << MaxIncrAge
             << " on this policy form."
@@ -1665,7 +1665,7 @@ void AccountValue::TxSetDeathBft(bool force_eoy_behavior)
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
 
@@ -1938,7 +1938,7 @@ void AccountValue::TxSetRiderDed()
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case '"
                     << WaiverChargeMethod
                     << "' not found."
@@ -2059,7 +2059,7 @@ void AccountValue::TxTakeSepAcctLoad()
             }
         if(0.0 != tiered_comp)
             {
-            fatal_error()
+            alarum()
                 << "Tiered asset-based compensation unimplemented."
                 << LMI_FLUSH
                 ;
@@ -2111,7 +2111,7 @@ void AccountValue::ApplyDynamicMandE(double assets)
             }
         case mce_gen_mdpt:
             {
-            fatal_error()
+            alarum()
                 << "Dynamic M&E not supported with midpoint expense basis."
                 << LMI_FLUSH
                 ;
@@ -2119,12 +2119,7 @@ void AccountValue::ApplyDynamicMandE(double assets)
             break;
         default:
             {
-            fatal_error()
-                << "Case "
-                << GenBasis_
-                << " not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case " << GenBasis_ << " not found." << LMI_FLUSH;
             }
         }
 
@@ -2136,7 +2131,7 @@ void AccountValue::ApplyDynamicMandE(double assets)
     double imf_rate = 
StratifiedCharges_->tiered_investment_management_fee(assets);
     if(0.0 != imf_rate)
         {
-        fatal_error()
+        alarum()
             << "Tiered investment management fee unimplemented."
             << LMI_FLUSH
             ;
@@ -2148,7 +2143,7 @@ void AccountValue::ApplyDynamicMandE(double assets)
             ;
     if(0.0 != asset_comp_rate)
         {
-        fatal_error()
+        alarum()
             << "Tiered asset-based compensation unimplemented."
             << LMI_FLUSH
             ;
@@ -2350,12 +2345,7 @@ double AccountValue::anticipated_deduction
             }
         default:
             {
-            fatal_error()
-                << "Case "
-                << method
-                << " not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case " << method << " not found." << LMI_FLUSH;
             throw "Unreachable--silences a compiler diagnostic.";
             }
         }
@@ -2657,7 +2647,7 @@ void AccountValue::TxTakeWD()
             break;
         default:
             {
-            fatal_error() << "Case " << YearsDBOpt << " not found." << 
LMI_FLUSH;
+            alarum() << "Case " << YearsDBOpt << " not found." << LMI_FLUSH;
             }
         }
 
@@ -2714,10 +2704,7 @@ void AccountValue::SetMaxLoan()
         ;
     if(0 != Month)
         {
-        fatal_error()
-            << "Off-anniversary loans untested."
-            << LMI_FLUSH
-            ;
+        alarum() << "Off-anniversary loans untested." << LMI_FLUSH;
         reg_loan_factor =
                 std::pow(1.0 + YearsRegLnIntDueRate, 12 - Month)
             -   1.0
@@ -2950,7 +2937,7 @@ void AccountValue::TxTestLapse()
             }
         else if(!HoneymoonActive && !Solving && lapse_test_csv < 0.0)
             {
-            fatal_error()
+            alarum()
                 << "Unloaned value not positive,"
                 << " no-lapse guarantee not active,"
                 << " and honeymoon not active, yet policy did not lapse."
diff --git a/ihs_avsolve.cpp b/ihs_avsolve.cpp
index 4510727..aeaad5e 100644
--- a/ihs_avsolve.cpp
+++ b/ihs_avsolve.cpp
@@ -391,12 +391,7 @@ double AccountValue::Solve
             break;
         default:
             {
-            fatal_error()
-                << "Case "
-                << a_SolveType
-                << " not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case " << a_SolveType << " not found." << LMI_FLUSH;
             }
         }
 
diff --git a/ihs_avstrtgy.cpp b/ihs_avstrtgy.cpp
index c529c12..49081fc 100644
--- a/ihs_avstrtgy.cpp
+++ b/ihs_avstrtgy.cpp
@@ -104,7 +104,7 @@ double AccountValue::CalculateSpecAmtFromStrategy
             }
         default:
             {
-            fatal_error() << "Case " << strategy << " not found." << LMI_FLUSH;
+            alarum() << "Case " << strategy << " not found." << LMI_FLUSH;
             throw "Unreachable--silences a compiler diagnostic.";
             }
         }
@@ -248,7 +248,7 @@ double AccountValue::DoPerformPmtStrategy
                     }
                 else
                     {
-                    fatal_error()
+                    alarum()
                         << "Type "
                         << a_SolveForWhichPrem
                         << " not allowed here."
@@ -309,7 +309,7 @@ double AccountValue::DoPerformPmtStrategy
             }
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << a_StrategyVector[Year]
                 << " not found."
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index fbda111..6c13186 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -151,7 +151,7 @@ void BasicValues::Init()
         &&  !global_settings::instance().regression_testing()
         )
         {
-        fatal_error()
+        alarum()
             << "Product "
             << yare_input_.ProductName
             << " not approved in state "
@@ -184,7 +184,7 @@ void BasicValues::Init()
 
     if(IssueAge < Database_->Query(DB_MinIssAge))
         {
-        fatal_error()
+        alarum()
             << "Issue age "
             << IssueAge
             << " less than minimum "
@@ -195,7 +195,7 @@ void BasicValues::Init()
         }
     if(Database_->Query(DB_MaxIssAge) < IssueAge)
         {
-        fatal_error()
+        alarum()
             << "Issue age "
             << IssueAge
             << " greater than maximum "
@@ -511,7 +511,7 @@ void BasicValues::Init7702()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.LoanRateType
                 << " not found."
@@ -743,10 +743,7 @@ void BasicValues::SetPermanentInvariants()
         &&  !(Database_->Query(DB_AllowSubstdTable) && mce_rated == 
yare_input_.UnderwritingClass)
         )
         {
-        fatal_error()
-            << "Substandard table ratings not permitted."
-            << LMI_FLUSH
-            ;
+        alarum() << "Substandard table ratings not permitted." << LMI_FLUSH;
         }
 
     // SOMEDAY !! WP and ADB shouldn't always be forbidden with table
@@ -760,14 +757,11 @@ void BasicValues::SetPermanentInvariants()
     // people they cover are unlikely to be underwritten.
     if(is_policy_rated(yare_input_) && yare_input_.WaiverOfPremiumBenefit)
         {
-        fatal_error()
-            << "Substandard waiver of premium not supported."
-            << LMI_FLUSH
-            ;
+        alarum() << "Substandard waiver of premium not supported." << 
LMI_FLUSH;
         }
     if(is_policy_rated(yare_input_) && yare_input_.AccidentalDeathBenefit)
         {
-        fatal_error()
+        alarum()
             << "Substandard accidental death rider not supported."
             << LMI_FLUSH
             ;
@@ -862,7 +856,7 @@ void BasicValues::SetMaxSurvivalDur()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.SurviveToType
                 << " not found."
@@ -920,7 +914,7 @@ double BasicValues::GetModalPrem
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Unknown modal premium type " << a_prem_type << '.'
             << LMI_FLUSH
             ;
@@ -1173,7 +1167,7 @@ double BasicValues::GetModalPremMlyDed
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case '"
                     << WaiverChargeMethod
                     << "' not found."
@@ -1255,7 +1249,7 @@ double BasicValues::GetModalPremMlyDedEe
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case '"
                     << WaiverChargeMethod
                     << "' not found."
@@ -1335,7 +1329,7 @@ double BasicValues::GetModalPremMlyDedEr
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case '"
                     << WaiverChargeMethod
                     << "' not found."
@@ -1404,7 +1398,7 @@ double BasicValues::GetModalSpecAmt
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Unknown modal premium type " << premium_type << '.'
             << LMI_FLUSH
             ;
@@ -1478,7 +1472,7 @@ double BasicValues::GetModalSpecAmtSalary(int a_year) 
const
 
 double BasicValues::GetModalSpecAmtMlyDed(double, mcenum_mode) const
 {
-    fatal_error()
+    alarum()
         << "No maximum specified amount is defined for this product."
         << LMI_FLUSH
         ;
@@ -1674,7 +1668,7 @@ std::vector<double> BasicValues::GetTable
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << CanBlendSmoking
                 << "' not found."
@@ -1703,7 +1697,7 @@ std::vector<double> BasicValues::GetTable
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << CanBlendGender
                 << "' not found."
@@ -1858,7 +1852,7 @@ std::vector<double> BasicValues::GetTable
         }
     else
         {
-        fatal_error() << "Invalid mortality blending." << LMI_FLUSH;
+        alarum() << "Invalid mortality blending." << LMI_FLUSH;
         }
 
     return BlendedTable;
@@ -1888,7 +1882,7 @@ std::vector<double> const& 
BasicValues::GetCorridorFactor() const
             }
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.DefinitionOfLifeInsurance
                 << " not found."
diff --git a/ihs_irc7702.cpp b/ihs_irc7702.cpp
index 42dffdd..4c9a257 100644
--- a/ihs_irc7702.cpp
+++ b/ihs_irc7702.cpp
@@ -810,7 +810,7 @@ std::vector<double> const& Irc7702::Corridor() const
         }
     else
         {
-        fatal_error() << "7702 test is neither GPT nor CVAT." << LMI_FLUSH;
+        alarum() << "7702 test is neither GPT nor CVAT." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -832,12 +832,7 @@ Irc7702::EIOBasis Irc7702::Get4PctBasis
             }
         default:
             {
-            fatal_error()
-                << "Case '"
-                << a_DBOpt
-                << "' not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case '" << a_DBOpt << "' not found." << LMI_FLUSH;
             throw "Unreachable--silences a compiler diagnostic.";
             }
         }
diff --git a/ihs_irc7702a.cpp b/ihs_irc7702a.cpp
index 11c076a..ec589b0 100644
--- a/ihs_irc7702a.cpp
+++ b/ihs_irc7702a.cpp
@@ -124,7 +124,7 @@ Irc7702A::Irc7702A
         case mce_later_of_increase_or_unnecessary_premium:
             {
             // TODO ?? TAXATION !! Not implemented yet.
-            fatal_error()
+            alarum()
                 << "mce_later_of_increase_or_unnecessary_premium not 
implemented."
                 << LMI_FLUSH
                 ;
@@ -152,7 +152,7 @@ Irc7702A::Irc7702A
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << DefnMaterialChange
                 << "' not found."
@@ -307,7 +307,7 @@ void Irc7702A::Initialize7702A
 
     if(!Use7PPTable || !UseNSPTable)
         {
-        fatal_error()
+        alarum()
             << "Present implementation requires 7702A factor tables."
             << LMI_FLUSH
             ;
@@ -1044,7 +1044,7 @@ void Irc7702A::TestBftDecrease(double a_NewBft)
         // to becoming a MEC in a past year, then we didn't add all the
         // payments together; but we don't need to, since we're a MEC
         // and the cumulative payments are no longer relevant.
-        fatal_error()
+        alarum()
             << "While processing a decrease in"
             << " policy month " << PolicyMonth
             << ", policy year " << PolicyYear
diff --git a/ihs_mortal.cpp b/ihs_mortal.cpp
index bd718e2..0b5c3e1 100644
--- a/ihs_mortal.cpp
+++ b/ihs_mortal.cpp
@@ -246,7 +246,7 @@ void 
MortalityRates::MakeCoiRateSubstandard(std::vector<double>& coi_rates)
 
     if(!(AllowFlatExtras_ || AllowSubstdTable_))
         {
-        fatal_error()
+        alarum()
             << "Flat extras and table ratings not permitted."
             << LMI_FLUSH
             ;
@@ -276,7 +276,7 @@ std::vector<double> const& 
MortalityRates::MonthlyCoiRatesBand0
         case mce_gen_curr: return MonthlyCurrentCoiRatesBand0_;
         case mce_gen_mdpt: return MonthlyMidpointCoiRatesBand0_;
         case mce_gen_guar: return MonthlyGuaranteedCoiRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
@@ -291,7 +291,7 @@ std::vector<double> const& 
MortalityRates::MonthlyCoiRatesBand1
         case mce_gen_curr: return MonthlyCurrentCoiRatesBand1_;
         case mce_gen_mdpt: return MonthlyMidpointCoiRatesBand1_;
         case mce_gen_guar: return MonthlyGuaranteedCoiRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
@@ -306,7 +306,7 @@ std::vector<double> const& 
MortalityRates::MonthlyCoiRatesBand2
         case mce_gen_curr: return MonthlyCurrentCoiRatesBand2_;
         case mce_gen_mdpt: return MonthlyMidpointCoiRatesBand2_;
         case mce_gen_guar: return MonthlyGuaranteedCoiRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
@@ -321,7 +321,7 @@ std::vector<double> const& MortalityRates::SpouseRiderRates
         case mce_gen_curr: return CurrentSpouseRiderRates_;
         case mce_gen_mdpt: return MidpointSpouseRiderRates_;
         case mce_gen_guar: return GuaranteedSpouseRiderRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
@@ -336,7 +336,7 @@ std::vector<double> const& 
MortalityRates::MonthlyTermCoiRates
         case mce_gen_curr: return MonthlyCurrentTermCoiRates_;
         case mce_gen_mdpt: return MonthlyMidpointTermCoiRates_;
         case mce_gen_guar: return MonthlyGuaranteedTermCoiRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
diff --git a/illustrator.cpp b/illustrator.cpp
index e3c260f..decf555 100644
--- a/illustrator.cpp
+++ b/illustrator.cpp
@@ -106,7 +106,7 @@ bool illustrator::operator()(fs::path const& file_path)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "File '"
             << file_path
             << "': extension '"
@@ -232,7 +232,7 @@ void assert_consistent_run_order
         {
         if(case_default["RunOrder"] != cell["RunOrder"])
             {
-            fatal_error()
+            alarum()
                 << "Case-default run order '"
                 << case_default["RunOrder"]
                 << "' differs from run order '"
@@ -287,7 +287,7 @@ void assert_okay_to_run_group_quote
 
     if(case_default["EffectiveDate"] != case_default["InforceAsOfDate"])
         {
-        fatal_error() << "Group quotes allowed for new business only." << 
LMI_FLUSH;
+        alarum() << "Group quotes allowed for new business only." << LMI_FLUSH;
         }
 
     int i = 0;
@@ -297,7 +297,7 @@ void assert_okay_to_run_group_quote
             {
             if(case_default[field] != cell[field])
                 {
-                fatal_error()
+                alarum()
                     << "Input field '"
                     << field
                     << "': value in cell number "
diff --git a/input_harmonization.cpp b/input_harmonization.cpp
index b8428af..1b834ca 100644
--- a/input_harmonization.cpp
+++ b/input_harmonization.cpp
@@ -174,7 +174,7 @@ void Input::DoHarmonize()
             }
         else
             {
-            fatal_error()
+            alarum()
                 << "No option selected for definition of life insurance."
                 << LMI_FLUSH
                 ;
@@ -980,7 +980,7 @@ void Input::set_solve_durations()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << SolveTgtAtWhich.value()
                 << "' not found."
@@ -1013,7 +1013,7 @@ void Input::set_solve_durations()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << SolveFromWhich.value()
                 << "' not found."
@@ -1046,7 +1046,7 @@ void Input::set_solve_durations()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case '"
                 << SolveToWhich.value()
                 << "' not found."
@@ -1134,7 +1134,7 @@ void Input::set_inforce_durations_from_dates()
         ,true
         );
     // After testing in production, either remove the "pyx" bypass, or
-    // redesign this. Replacing fatal_error() with warning() would cause
+    // redesign this. Replacing alarum() with warning() would cause
     // multiple messageboxes, which is unavoidable if the diagnostic is
     // to be given when GUI input enters an invalid state, and also
     // whenever an illustration is about to be produced.
@@ -1150,7 +1150,7 @@ if(1 != InforceDataSource.value())
   {
     if(expected != InforceAsOfDate.value() && 
!contains(global_settings::instance().pyx(), "off_monthiversary"))
         {
-        fatal_error()
+        alarum()
             << "Input inforce-as-of date, "
             << InforceAsOfDate.value().str()
             << ", should be an exact monthiversary date."
@@ -1173,7 +1173,7 @@ if(1 != InforceDataSource.value())
         && (0 == InforceYear && 0 == InforceMonth)
         )
         {
-        fatal_error()
+        alarum()
             << "Inforce illustrations not permitted during month of issue."
             << LMI_FLUSH
             ;
diff --git a/input_realization.cpp b/input_realization.cpp
index 275f7a9..272ac80 100644
--- a/input_realization.cpp
+++ b/input_realization.cpp
@@ -257,7 +257,7 @@ std::vector<std::string> 
Input::RealizeAllSequenceInput(bool report_errors)
                 }
             if(diagnostics_present)
                 {
-                fatal_error()
+                alarum()
                     << "Input validation problems for '"
                     << InsuredName
                     << "':\n"
@@ -1104,10 +1104,7 @@ void Input::make_term_rider_consistent(bool aggressively)
         }
     else
         {
-        fatal_error()
-            << "Term is neither proportional nor absolute."
-            << LMI_FLUSH
-            ;
+        alarum() << "Term is neither proportional nor absolute." << LMI_FLUSH;
         }
 
     if
diff --git a/input_sequence.cpp b/input_sequence.cpp
index fd20f10..88c3b63 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -321,7 +321,7 @@ std::string InputSequence::canonical_form() const
             {
             case e_invalid_mode:
                 {
-                fatal_error() << "Invalid mode." << LMI_FLUSH;
+                alarum() << "Invalid mode." << LMI_FLUSH;
                 }
                 break;
             case e_duration:
@@ -351,12 +351,12 @@ std::string InputSequence::canonical_form() const
                 break;
             case e_inception:
                 {
-                fatal_error() << "Interval ended at inception." << LMI_FLUSH;
+                alarum() << "Interval ended at inception." << LMI_FLUSH;
                 }
                 break;
             case e_inforce:
                 {
-                fatal_error() << "'e_inforce' not implemented." << LMI_FLUSH;
+                alarum() << "'e_inforce' not implemented." << LMI_FLUSH;
                 }
                 break;
             case e_retirement:
@@ -410,14 +410,11 @@ void assert_not_insane_or_disordered
         {
         if(i.insane)
             {
-            fatal_error()
-                << "Untrapped parser error."
-                << LMI_FLUSH
-                ;
+            alarum() << "Untrapped parser error." << LMI_FLUSH;
             }
         if(i.value_is_keyword && "daft" == i.value_keyword)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -427,7 +424,7 @@ void assert_not_insane_or_disordered
             }
         if(e_invalid_mode == i.begin_mode)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -437,7 +434,7 @@ void assert_not_insane_or_disordered
             }
         if(e_invalid_mode == i.end_mode)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -447,7 +444,7 @@ void assert_not_insane_or_disordered
             }
         if(i.begin_duration < 0)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -457,7 +454,7 @@ void assert_not_insane_or_disordered
             }
         if(i.end_duration < i.begin_duration)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -467,7 +464,7 @@ void assert_not_insane_or_disordered
             }
         if(years_to_maturity < i.end_duration)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
@@ -477,7 +474,7 @@ void assert_not_insane_or_disordered
             }
         if(i.begin_duration < prior_begin_duration)
             {
-            fatal_error()
+            alarum()
                 << "Previous interval began at duration "
                 << prior_begin_duration
                 << "; current interval "
@@ -654,7 +651,7 @@ void assert_sane_and_ordered_partition
         {
         if(i.begin_duration != prior_end_duration)
             {
-            fatal_error()
+            alarum()
                 << "Interval "
                 << "[ " << i.begin_duration
                 << ", " << i.end_duration << " )"
diff --git a/input_sequence_aux.hpp b/input_sequence_aux.hpp
index 74015db..00297cb 100644
--- a/input_sequence_aux.hpp
+++ b/input_sequence_aux.hpp
@@ -85,7 +85,7 @@ namespace detail
             else
                 {
                 dst[j] = T(); // COMPILER !! Cuz we can't throw...see below.
-                fatal_error()
+                alarum()
                     << "Key '"
                     << src[j]
                     << "' not found in map."
diff --git a/input_sequence_entry.cpp b/input_sequence_entry.cpp
index 4663110..b428c7e 100644
--- a/input_sequence_entry.cpp
+++ b/input_sequence_entry.cpp
@@ -147,7 +147,7 @@ void DurationModeChoice::value(duration_mode x)
             }
         }
 
-    fatal_error() << "unexpected duration_mode value" << LMI_FLUSH;
+    alarum() << "Unexpected duration_mode value." << LMI_FLUSH;
 }
 
 duration_mode DurationModeChoice::value() const
@@ -527,7 +527,7 @@ std::string InputSequenceEditor::sequence_string()
             case e_inception:
             case e_inforce:
                 {
-                fatal_error() << "unexpected duration_mode value" << LMI_FLUSH;
+                alarum() << "Unexpected duration_mode value." << LMI_FLUSH;
                 }
                 break;
             }
@@ -985,7 +985,7 @@ wxString InputSequenceEditor::format_from_text(int row)
         case e_inception:
         case e_inforce:
             {
-            fatal_error() << "unexpected duration_mode value" << LMI_FLUSH;
+            alarum() << "Unexpected duration_mode value." << LMI_FLUSH;
             return "";
             }
         }
@@ -1050,7 +1050,7 @@ int InputSequenceEditor::compute_duration_scalar(int row)
         case e_inception:
         case e_inforce:
             {
-            fatal_error() << "unexpected duration_mode value" << LMI_FLUSH;
+            alarum() << "Unexpected duration_mode value." << LMI_FLUSH;
             return 0;
             }
         }
@@ -1094,7 +1094,7 @@ void InputSequenceEditor::adjust_duration_num_range(int 
row)
         case e_inception:
         case e_inforce:
             {
-            fatal_error() << "unexpected duration_mode value" << LMI_FLUSH;
+            alarum() << "Unexpected duration_mode value." << LMI_FLUSH;
             break;
             }
         }
diff --git a/input_xml_io.cpp b/input_xml_io.cpp
index b0268b0..193c4b1 100644
--- a/input_xml_io.cpp
+++ b/input_xml_io.cpp
@@ -447,7 +447,7 @@ void Input::redintegrate_ex_post
         bool const b1 = !contains(residuary_names, "PremiumTaxState");
         if(b0 || b1)
             {
-            fatal_error() << "Unexpected 'state' fields." << LMI_FLUSH; // 
deficient_extract
+            alarum() << "Unexpected 'state' fields." << LMI_FLUSH; // 
deficient_extract
             LMI_ASSERT(b0 && b1 && 5 == file_version);
             StateOfJurisdiction = map_lookup(detritus_map, 
"FilingApprovalState");
             }
@@ -466,7 +466,7 @@ void Input::redintegrate_ex_post
             // Deemed state must not depend on itself.
             if(db.varies_by_state(DB_PremTaxState))
                 {
-                fatal_error()
+                alarum()
                     << "Database invalid: circular dependency."
                     << " State of jurisdiction depends on itself."
                     << LMI_FLUSH
@@ -489,7 +489,7 @@ void Input::redintegrate_ex_post
                     break;
                 default:
                     {
-                    fatal_error()
+                    alarum()
                         << "Cannot determine state of jurisdiction."
                         << LMI_FLUSH
                         ;
diff --git a/interest_rates.cpp b/interest_rates.cpp
index f533cc3..40722e6 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -136,7 +136,7 @@ double transform_annual_gross_rate_to_annual_net
         }
     else
         {
-        fatal_error() << "No " << spread_method << " case." << LMI_FLUSH;
+        alarum() << "No " << spread_method << " case." << LMI_FLUSH;
         }
     return std::max(floor, i);
 }
@@ -385,7 +385,7 @@ void InterestRates::Initialize(BasicValues const& v)
             break;
         default:
             {
-            fatal_error() << "No " << LoanRateType_ << " case." << LMI_FLUSH;
+            alarum() << "No " << LoanRateType_ << " case." << LMI_FLUSH;
             }
         }
 
@@ -444,7 +444,7 @@ void InterestRates::InitializeGeneralAccountRates()
     std::vector<double> spread[mc_n_gen_bases] = {Zero_, Zero_, Zero_};
     if(mce_earned_rate == GenAcctRateType_)
         {
-        fatal_error()
+        alarum()
             << "General-account rate is unexpectedly an earned rate."
             << LMI_FLUSH
             ;
@@ -549,7 +549,7 @@ void InterestRates::InitializeSeparateAccountRates()
     // neither is the implicit net rate.
     if(mce_net_rate == SepAcctRateType_)
         {
-        fatal_error()
+        alarum()
             << "Separate-account rate is unexpectedly a net rate."
             << LMI_FLUSH
             ;
@@ -830,7 +830,7 @@ void InterestRates::DynamicMlySepAcctRate
             {
             if(mce_gen_mdpt == gen_basis)
                 {
-                fatal_error()
+                alarum()
                     << "Midpoint separate-account rate not supported."
                     << LMI_FLUSH
                     ;
@@ -857,12 +857,12 @@ void InterestRates::DynamicMlySepAcctRate
             break;
         case mce_net_rate:
             {
-            fatal_error() << "Net rate not supported." << LMI_FLUSH;
+            alarum() << "Net rate not supported." << LMI_FLUSH;
             }
             break;
         default:
             {
-            fatal_error() << "No " << SepAcctRateType_ << " case." << 
LMI_FLUSH;
+            alarum() << "No " << SepAcctRateType_ << " case." << LMI_FLUSH;
             }
         }
 }
@@ -1079,7 +1079,7 @@ void InterestRates::Initialize7702Rates()
             break;
         default:
             {
-            fatal_error() << "No " << LoanRateType_ << " case." << LMI_FLUSH;
+            alarum() << "No " << LoanRateType_ << " case." << LMI_FLUSH;
             }
         }
 */
diff --git a/ledger.cpp b/ledger.cpp
index 191de92..c89ebcd 100644
--- a/ledger.cpp
+++ b/ledger.cpp
@@ -125,12 +125,7 @@ void Ledger::SetRunBases(int length)
 #endif
         default:
             {
-            fatal_error()
-                << "Case '"
-                << ledger_type_
-                << "' not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case '" << ledger_type_ << "' not found." << 
LMI_FLUSH;
             }
         }
 
@@ -205,7 +200,7 @@ Ledger& Ledger::PlusEq(Ledger const& a_Addend)
 
     if(ledger_type_ != a_Addend.ledger_type())
         {
-        fatal_error()
+        alarum()
             << "Cannot add ledgers for products with different"
             << " formatting requirements."
             << LMI_FLUSH
@@ -274,7 +269,7 @@ void Ledger::SetOneLedgerVariant
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Failed attempt to set ledger for unused basis '"
             << mc_str(a_Basis)
             << "'."
@@ -562,7 +557,7 @@ void throw_if_interdicted(Ledger const& z)
     std::string s = reason_to_interdict(z);
     if(!s.empty())
         {
-        fatal_error() << s << LMI_FLUSH;
+        alarum() << s << LMI_FLUSH;
         }
 }
 
diff --git a/ledger_base.cpp b/ledger_base.cpp
index 99f756d..aec19d8 100644
--- a/ledger_base.cpp
+++ b/ledger_base.cpp
@@ -148,12 +148,7 @@ std::string LedgerBase::value_str(std::string const& 
map_key, int index) const
         return value_cast<std::string>((*(*found).second)[index]);
         }
 
-    fatal_error()
-        << "Map key '"
-        << map_key
-        << "' not found."
-        << LMI_FLUSH
-        ;
+    alarum() << "Map key '" << map_key << "' not found." << LMI_FLUSH;
     return "";
 }
 
@@ -172,12 +167,7 @@ std::string LedgerBase::value_str(std::string const& 
map_key) const
         return value_cast<std::string>(*(*found_scalar).second);
         }
 
-    fatal_error()
-        << "Map key '"
-        << map_key
-        << "' not found."
-        << LMI_FLUSH
-        ;
+    alarum() << "Map key '" << map_key << "' not found." << LMI_FLUSH;
     return "";
 }
 
@@ -241,7 +231,7 @@ LedgerBase& LedgerBase::PlusEq
     LMI_ASSERT(0.0 != m_scaling_factor);
     if(m_scaling_factor != a_Addend.m_scaling_factor)
         {
-        fatal_error() << "Cannot add differently scaled ledgers." << LMI_FLUSH;
+        alarum() << "Cannot add differently scaled ledgers." << LMI_FLUSH;
         }
 
     double_vector_map::const_iterator a_Addend_svmi;
@@ -415,12 +405,7 @@ namespace
                 //  break;
             default:
                 {
-                fatal_error()
-                    << "Case '"
-                    << z
-                    << "' not found."
-                    << LMI_FLUSH
-                    ;
+                alarum() << "Case '" << z << "' not found." << LMI_FLUSH;
                 throw "Unreachable--silences a compiler diagnostic.";
                 }
             }
diff --git a/ledger_invariant.cpp b/ledger_invariant.cpp
index e5169c3..f0b6f24 100644
--- a/ledger_invariant.cpp
+++ b/ledger_invariant.cpp
@@ -860,7 +860,7 @@ void LedgerInvariant::Init(BasicValues const* b)
                 break;
             default:
                 {
-                fatal_error()
+                alarum()
                     << "Case '"
                     << smoke_or_tobacco
                     << "' not found."
@@ -928,7 +928,7 @@ if(1 != b->yare_input_.InforceDataSource)
   {
     if(IsInforce && (0 == b->yare_input_.InforceYear && 0 == 
b->yare_input_.InforceMonth))
         {
-        fatal_error()
+        alarum()
             << "Inforce illustrations not permitted during month of issue."
             << LMI_FLUSH
             ;
diff --git a/ledger_text_formats.cpp b/ledger_text_formats.cpp
index 27ff87b..410dcea 100644
--- a/ledger_text_formats.cpp
+++ b/ledger_text_formats.cpp
@@ -665,10 +665,7 @@ void PrintCellTabDelimited
 
         if(contains(bases, mce_run_gen_curr_sep_half))
             {
-            fatal_error()
-                << "Three-rate illustrations not supported."
-                << LMI_FLUSH
-                ;
+            alarum() << "Three-rate illustrations not supported." << LMI_FLUSH;
             }
 
         os << Invar.value_str("ProducerCompensation"  ,j) << '\t';
@@ -677,7 +674,7 @@ void PrintCellTabDelimited
         }
     if(!os)
         {
-        fatal_error() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
+        alarum() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
         }
 }
 
@@ -756,7 +753,7 @@ void PrintRosterHeaders(std::string const& file_name)
 
     if(!os)
         {
-        fatal_error() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
+        alarum() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
         }
 }
 
@@ -831,7 +828,7 @@ void PrintRosterTabDelimited
 
     if(!os)
         {
-        fatal_error() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
+        alarum() << "Unable to write '" << file_name << "'." << LMI_FLUSH;
         }
 }
 
@@ -1187,7 +1184,7 @@ std::string ledger_format
     interpreter >> s;
     if(!interpreter.eof())
         {
-        fatal_error() << "Formatting error." << LMI_FLUSH;
+        alarum() << "Formatting error." << LMI_FLUSH;
         }
 
     if(f.second)
diff --git a/ledger_xml_io.cpp b/ledger_xml_io.cpp
index c980da4..4a36492 100644
--- a/ledger_xml_io.cpp
+++ b/ledger_xml_io.cpp
@@ -911,7 +911,7 @@ void Ledger::write(xml::element& x) const
             }
         if(!ofs)
             {
-            fatal_error() << "Unable to write '" << filepath << "'." << 
LMI_FLUSH;
+            alarum() << "Unable to write '" << filepath << "'." << LMI_FLUSH;
             }
         }
 }
diff --git a/ledger_xsl.cpp b/ledger_xsl.cpp
index 7712a49..ba480d7 100644
--- a/ledger_xsl.cpp
+++ b/ledger_xsl.cpp
@@ -52,7 +52,7 @@ std::string xsl_filename(Ledger const& ledger)
         case mce_variable_annuity:             return "variable_annuity.xsl";
         default:
             {
-            fatal_error() << "Case '" << z << "' not found." << LMI_FLUSH;
+            alarum() << "Case '" << z << "' not found." << LMI_FLUSH;
             }
         }
     throw "Unreachable--silences a compiler diagnostic.";
@@ -67,7 +67,7 @@ fs::path xsl_filepath(Ledger const& ledger)
     fs::path xsl_file(global_settings::instance().data_directory() / xsl_name);
     if(!fs::exists(xsl_file))
         {
-        fatal_error()
+        alarum()
             << "Unable to read file '"
             << xsl_file
             << "' required for ledger type '"
@@ -113,7 +113,7 @@ std::string write_ledger_as_pdf(Ledger const& ledger, 
fs::path const& filepath)
         ofs.close();
         if(!ofs.good())
             {
-            fatal_error()
+            alarum()
                 << "Unable to write output file '"
                 << xml_file
                 << "'."
@@ -129,7 +129,7 @@ std::string write_ledger_as_pdf(Ledger const& ledger, 
fs::path const& filepath)
     ofs.close();
     if(!ofs.good())
         {
-        fatal_error()
+        alarum()
             << "Unable to write output file '"
             << xml_fo_file
             << "'."
diff --git a/loads.cpp b/loads.cpp
index 724cb6c..af5aca2 100644
--- a/loads.cpp
+++ b/loads.cpp
@@ -213,7 +213,7 @@ void Loads::Calculate(load_details const& details)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Case '"
             << details.asset_charge_type_
             << "' not found."
@@ -285,7 +285,7 @@ void Loads::Calculate(load_details const& details)
             < monthly_policy_fee_[mce_gen_curr][j]
             )
             {
-            fatal_error()
+            alarum()
                 << "Duration "
                 << j
                 << ": current monthly policy fee "
@@ -335,7 +335,7 @@ void Loads::Calculate(load_details const& details)
 
 void Loads::AmortizePremiumTax(load_details const&)
 {
-    fatal_error() << "Premium-tax amortization not implemented." << LMI_FLUSH;
+    alarum() << "Premium-tax amortization not implemented." << LMI_FLUSH;
 }
 
 /// Ctor for antediluvian branch.
diff --git a/main_cgi.cpp b/main_cgi.cpp
index 8b9ccf3..722557c 100644
--- a/main_cgi.cpp
+++ b/main_cgi.cpp
@@ -605,7 +605,7 @@ void ShowCensusOutput
             }
         if(values.size() != headers.size())
             {
-            fatal_error()
+            alarum()
                 << "Line #" << current_line << ":<BR>"
                 << "  (" << line << ")<BR>"
                 << "should have one value per column.<BR>"
diff --git a/mc_enum.tpp b/mc_enum.tpp
index 85c9abd..9a74935 100644
--- a/mc_enum.tpp
+++ b/mc_enum.tpp
@@ -92,7 +92,7 @@ std::size_t mc_enum<T>::ordinal(std::string const& s)
     std::size_t v = std::find(c(), c() + n(), s) - c();
     if(v == n())
         {
-        fatal_error()
+        alarum()
             << "Value '"
             << s
             << "' invalid for type '"
@@ -137,7 +137,7 @@ std::size_t mc_enum<T>::ordinal() const
     std::size_t i = std::find(e(), e() + n(), value_) - e();
     if(i == n())
         {
-        fatal_error()
+        alarum()
             << "Value "
             << value_
             << " invalid for type '"
diff --git a/mc_enum_types_aux.cpp b/mc_enum_types_aux.cpp
index 832a754..59a39c0 100644
--- a/mc_enum_types_aux.cpp
+++ b/mc_enum_types_aux.cpp
@@ -99,7 +99,7 @@ mcenum_dbopt_7702 effective_dbopt_7702
         case mce_option1: return mce_option1_for_7702;
         case mce_option2: return mce_option2_for_7702;
         case mce_rop:     return rop_equivalent      ;
-        default: fatal_error() << "No " << actual_dbopt << " case." << 
LMI_FLUSH;
+        default: alarum() << "No " << actual_dbopt << " case." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
@@ -173,7 +173,7 @@ void set_cloven_bases_from_run_basis
     else if(r == mce_run_gen_guar_sep_zero) {g = mce_gen_guar; s = 
mce_sep_zero;}
     else if(r == mce_run_gen_curr_sep_half) {g = mce_gen_curr; s = 
mce_sep_half;}
     else if(r == mce_run_gen_guar_sep_half) {g = mce_gen_guar; s = 
mce_sep_half;}
-    else {fatal_error() << "Run basis " << r << " unknown." << LMI_FLUSH;}
+    else {alarum() << "Run basis " << r << " unknown." << LMI_FLUSH;}
 }
 
 /// Illustrations are run on two primary bases:
@@ -213,6 +213,6 @@ void set_run_basis_from_cloven_bases
     else if(g == mce_gen_guar && s == mce_sep_zero) r = 
mce_run_gen_guar_sep_zero;
     else if(g == mce_gen_curr && s == mce_sep_half) r = 
mce_run_gen_curr_sep_half;
     else if(g == mce_gen_guar && s == mce_sep_half) r = 
mce_run_gen_guar_sep_half;
-    else {fatal_error() << "Cannot set run basis." << LMI_FLUSH;}
+    else {alarum() << "Cannot set run basis." << LMI_FLUSH;}
 }
 
diff --git a/mec_input.cpp b/mec_input.cpp
index 917e395..757ded3 100644
--- a/mec_input.cpp
+++ b/mec_input.cpp
@@ -325,7 +325,7 @@ void mec_input::DoHarmonize()
         }
     else
         {
-        fatal_error()
+        alarum()
             << "No option selected for definition of life insurance."
             << LMI_FLUSH
             ;
@@ -538,7 +538,7 @@ std::vector<std::string> 
mec_input::RealizeAllSequenceInput(bool report_errors)
                 }
             if(diagnostics_present)
                 {
-                fatal_error()
+                alarum()
                     << "Input validation problems:\n"
                     << oss.str()
                     << LMI_FLUSH
diff --git a/mec_server.cpp b/mec_server.cpp
index 28668f9..3916e6d 100644
--- a/mec_server.cpp
+++ b/mec_server.cpp
@@ -291,7 +291,7 @@ mec_state test_one_days_7702A_transactions
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Unknown modal premium type " << target_premium_type << '.'
             << LMI_FLUSH
             ;
@@ -514,7 +514,7 @@ bool mec_server::operator()(fs::path const& file_path)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "File '"
             << file_path
             << "': extension '"
diff --git a/menus.xrc b/menus.xrc
index 5c7ac45..a534721 100644
--- a/menus.xrc
+++ b/menus.xrc
@@ -201,14 +201,14 @@
         <object class="wxMenuItem" name="test_app_hobsons_choice_alert">
             <label>Test _hobsons-choice alert</label>
         </object>
-        <object class="wxMenuItem" name="test_app_fatal_error_alert">
-            <label>Test _fatal-error alert</label>
+        <object class="wxMenuItem" name="test_app_alarum_alert">
+            <label>Test _alarum alert</label>
         </object>
         <object class="wxMenuItem" name="test_app_standard_exception">
             <label>Test standard _exception</label>
         </object>
         <object class="wxMenuItem" name="test_app_arbitrary_exception">
-            <label>Test _arbitrary exception</label>
+            <label>Test arbitrary e_xception</label>
         </object>
     </object>
     <object class="wxMenu">
@@ -222,14 +222,14 @@
         <object class="wxMenuItem" name="test_lib_hobsons_choice_alert">
             <label>Test _hobsons-choice alert</label>
         </object>
-        <object class="wxMenuItem" name="test_lib_fatal_error_alert">
-            <label>Test _fatal-error alert</label>
+        <object class="wxMenuItem" name="test_lib_alarum_alert">
+            <label>Test _alarum alert</label>
         </object>
         <object class="wxMenuItem" name="test_lib_standard_exception">
             <label>Test standard _exception</label>
         </object>
         <object class="wxMenuItem" name="test_lib_arbitrary_exception">
-            <label>Test _arbitrary exception</label>
+            <label>Test arbitrary e_xception</label>
         </object>
         <object class="wxMenuItem" name="test_lib_catastrophe_report">
             <label>Test _catastrophe report</label>
diff --git a/miscellany.cpp b/miscellany.cpp
index 56d991c..473e036 100644
--- a/miscellany.cpp
+++ b/miscellany.cpp
@@ -62,8 +62,8 @@ bool files_are_identical(std::string const& file0, 
std::string const& file1)
 {
     std::ifstream ifs0(file0.c_str(), ios_in_binary());
     std::ifstream ifs1(file1.c_str(), ios_in_binary());
-    if(!ifs0) fatal_error() << "Unable to open '" << file0 << "'." << 
LMI_FLUSH;
-    if(!ifs1) fatal_error() << "Unable to open '" << file1 << "'." << 
LMI_FLUSH;
+    if(!ifs0) alarum() << "Unable to open '" << file0 << "'." << LMI_FLUSH;
+    if(!ifs1) alarum() << "Unable to open '" << file1 << "'." << LMI_FLUSH;
     return streams_are_identical(ifs0, ifs1);
 }
 
diff --git a/mortality_rates.cpp b/mortality_rates.cpp
index 8956316..6d447bc 100644
--- a/mortality_rates.cpp
+++ b/mortality_rates.cpp
@@ -102,7 +102,7 @@ std::vector<double> const& MortalityRates::MonthlyCoiRates
         case mce_gen_curr: return MonthlyCurrentCoiRatesBand0_;
         case mce_gen_mdpt: return MonthlyMidpointCoiRatesBand0_;
         case mce_gen_guar: return MonthlyGuaranteedCoiRates_;
-        default: fatal_error() << "Case " << b << " not found." << LMI_FLUSH;
+        default: alarum() << "Case " << b << " not found." << LMI_FLUSH;
         }
     throw "Unreachable--silences a compiler diagnostic.";
 }
diff --git a/msw_workarounds.cpp b/msw_workarounds.cpp
index 3572940..ac5380c 100644
--- a/msw_workarounds.cpp
+++ b/msw_workarounds.cpp
@@ -58,7 +58,7 @@ MswDllPreloader& MswDllPreloader::instance()
     catch(...)
         {
         report_exception();
-        fatal_error() << "Instantiation failed." << LMI_FLUSH;
+        alarum() << "Instantiation failed." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/multidimgrid_any.cpp b/multidimgrid_any.cpp
index 0d8d9aa..3a0b206 100644
--- a/multidimgrid_any.cpp
+++ b/multidimgrid_any.cpp
@@ -322,7 +322,7 @@ bool MultiDimGrid::Create
     table_ = atable;
     if(!table_)
         {
-        fatal_error() << "Table cannot be null." << LMI_FLUSH;
+        alarum() << "Table cannot be null." << LMI_FLUSH;
         }
     dimension_ = table().GetDimension();
 
@@ -333,10 +333,7 @@ bool MultiDimGrid::Create
     axis_ = table().GetAxesAny();
     if(dimension_ != axis_.size())
         {
-        fatal_error()
-            << "Table size does not match number of axes."
-            << LMI_FLUSH
-            ;
+        alarum() << "Table size does not match number of axes." << LMI_FLUSH;
         }
 
     // initializing fixed values with empty ones
@@ -883,7 +880,7 @@ bool MultiDimGrid::SetGridAxisSelection(int firstAxis, int 
secondAxis)
 {
     if(firstAxis == secondAxis && firstAxis != wxNOT_FOUND)
         {
-        fatal_error() << "Select different axes." << LMI_FLUSH;
+        alarum() << "Select different axes." << LMI_FLUSH;
         return false;
         }
     bool update =
@@ -1118,7 +1115,7 @@ MultiDimGrid::Coords const& 
MultiDimGrid::PrepareFixedCoords(int row, int col) c
         {
         if(col != 0)
             {
-            fatal_error() << "No first grid axis selected." << LMI_FLUSH;
+            alarum() << "No first grid axis selected." << LMI_FLUSH;
             }
         }
 
@@ -1131,7 +1128,7 @@ MultiDimGrid::Coords const& 
MultiDimGrid::PrepareFixedCoords(int row, int col) c
         {
         if(row != 0)
             {
-            fatal_error() << "No second grid axis selected." << LMI_FLUSH;
+            alarum() << "No second grid axis selected." << LMI_FLUSH;
             }
         }
     return axis_fixed_coords_;
@@ -1252,10 +1249,7 @@ void MultiDimGrid::UponAxisVariesToggle(wxCommandEvent& 
event)
 
     if(it == axis_varies_checkboxes_.end())
         {
-        fatal_error()
-            << "Event received from unexpected control."
-            << LMI_FLUSH
-            ;
+        alarum() << "Event received from unexpected control." << LMI_FLUSH;
         }
 
     std::size_t index = it - axis_varies_checkboxes_.begin();
@@ -1301,10 +1295,7 @@ void 
MultiDimGrid::UponSwitchSelectedAxis(wxCommandEvent& event)
     int id = event.GetId();
     if(id != e_axis_x && id != e_axis_y)
         {
-        fatal_error()
-            << "Event received from unexpected control."
-            << LMI_FLUSH
-            ;
+        alarum() << "Event received from unexpected control." << LMI_FLUSH;
         }
 
     DoOnSwitchSelectedAxis(static_cast<enum_axis_x_or_y>(id));
@@ -1339,7 +1330,7 @@ unsigned int MultiDimGrid::EnsureIndexIsPositive(int 
row_or_col) const
 {
     if(row_or_col < 0)
         {
-        fatal_error()
+        alarum()
             << "Row or column index "
             << row_or_col
             << " is negative."
@@ -1414,7 +1405,7 @@ void MultiDimAxisAnyChoice::SelectionChanged()
     int const sel = GetSelection();
     if(!(0 <= sel && static_cast<unsigned int>(sel) < axis_.GetCardinality()))
         {
-        fatal_error()
+        alarum()
             << "The axis is inconsistent with its choice control."
             << LMI_FLUSH
             ;
diff --git a/multidimgrid_any.hpp b/multidimgrid_any.hpp
index e0159cb..ce2dfc6 100644
--- a/multidimgrid_any.hpp
+++ b/multidimgrid_any.hpp
@@ -360,7 +360,7 @@ inline boost::any MultiDimTableAny::GetValueAny(Coords 
const& coords) const
 {
     if(coords.size() != GetDimension())
         {
-        fatal_error() << "Incorrect dimension." << LMI_FLUSH;
+        alarum() << "Incorrect dimension." << LMI_FLUSH;
         }
     return DoGetValueAny(coords);
 }
@@ -371,7 +371,7 @@ inline void MultiDimTableAny::SetValueAny
 {
     if(coords.size() != GetDimension())
         {
-        fatal_error() << "Incorrect dimension." << LMI_FLUSH;
+        alarum() << "Incorrect dimension." << LMI_FLUSH;
         }
     DoSetValueAny(coords, value);
 }
@@ -715,7 +715,7 @@ inline unsigned int 
MultiDimGrid::DoGetAxisIndexByName(std::string const& name)
     int n = GetAxisIndexByName(name);
     if(n == wxNOT_FOUND || static_cast<int>(dimension_) <= n)
         {
-        fatal_error() << "Unknown axis '" << name << "'." << LMI_FLUSH;
+        alarum() << "Unknown axis '" << name << "'." << LMI_FLUSH;
         }
     return static_cast<unsigned int>(n);
 }
diff --git a/multidimgrid_safe.tpp b/multidimgrid_safe.tpp
index 9c388a2..a91d337 100644
--- a/multidimgrid_safe.tpp
+++ b/multidimgrid_safe.tpp
@@ -121,14 +121,11 @@ void MultiDimIntegralAxis<Integral>::SetValues
 {
     if(!(min_value <= max_value))
         {
-        fatal_error()
-            << "Minimum value exceeds maximum value."
-            << LMI_FLUSH
-            ;
+        alarum() << "Minimum value exceeds maximum value." << LMI_FLUSH;
         }
     if(step < 1)
         {
-        fatal_error() << "Step must be at least 1." << LMI_FLUSH;
+        alarum() << "Step must be at least 1." << LMI_FLUSH;
         }
 
     min_ = min_value;
@@ -271,11 +268,7 @@ A MultiDimTable<T, D, C>::UnwrapAny(boost::any const& any)
         }
     catch(boost::bad_any_cast const& e)
         {
-        fatal_error()
-            << "Type mismatch : "
-            << e.what()
-            << LMI_FLUSH
-            ;
+        alarum() << "Type mismatch : " << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/multidimgrid_tools.hpp b/multidimgrid_tools.hpp
index 4b535bf..374b07e 100644
--- a/multidimgrid_tools.hpp
+++ b/multidimgrid_tools.hpp
@@ -125,7 +125,7 @@ AxisMaxBoundAdjuster<Integral>::AxisMaxBoundAdjuster
 {
     if(maximum_upper_bound < maximum_lower_bound)
         {
-        fatal_error()
+        alarum()
             << "Invalid bounds ["
             << maximum_lower_bound
             << ","
@@ -183,7 +183,7 @@ void 
AxisMaxBoundAdjuster<Integral>::EnsureValidMaximumAxisValue
 {
     if(max_value < maximum_lower_bound_ || maximum_upper_bound_ < max_value)
         {
-        fatal_error()
+        alarum()
             << "Maximum value ("
             << max_value
             << ") is outside allowed range ["
@@ -321,10 +321,7 @@ void AdjustableMaxBoundAxis<Integral>::SetBounds(Integral 
lower_bound, Integral
 {
     if(lower_bound < 0 || upper_bound < lower_bound)
         {
-        fatal_error()
-            << "Bounds are invalid."
-            << LMI_FLUSH
-            ;
+        alarum() << "Bounds are invalid." << LMI_FLUSH;
         }
     lower_bound_ = lower_bound;
     upper_bound_ = upper_bound;
@@ -396,10 +393,7 @@ bool AdjustableMaxBoundAxis<Integral>::DoApplyAdjustment
     Integral const new_max_value = adjust_window.GetMaximumAxisValue();
     if(!(lower_bound_ <= new_max_value && new_max_value <= upper_bound_))
         {
-        fatal_error()
-            << "New maximum value is outside valid range."
-            << LMI_FLUSH
-            ;
+        alarum() << "New maximum value is outside valid range." << LMI_FLUSH;
         }
     bool const updated = (GrandBaseClass::GetMaxValue() != new_max_value);
     SetMaxValue(new_max_value);
diff --git a/multiple_cell_document.cpp b/multiple_cell_document.cpp
index c602eb4..834cc4d 100644
--- a/multiple_cell_document.cpp
+++ b/multiple_cell_document.cpp
@@ -129,7 +129,7 @@ void multiple_cell_document::parse(xml_lmi::dom_parser 
const& parser)
     LMI_ASSERT(0 < file_version);
     if(class_version() < file_version)
         {
-        fatal_error() << "Incompatible file version." << LMI_FLUSH;
+        alarum() << "Incompatible file version." << LMI_FLUSH;
         }
 
     if(data_source_is_external(parser.document()))
@@ -187,7 +187,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
     LMI_ASSERT(i != elements.end());
     if("cell" != xml_lmi::get_name(*i))
         {
-        fatal_error()
+        alarum()
             << "XML node name is '"
             << xml_lmi::get_name(*i)
             << "' but '"
@@ -205,7 +205,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
         xml_lmi::get_attr(*i, "version", version);
         if(5 != version)
             {
-            fatal_error()
+            alarum()
                 << "Case-default 'cell' element is empty, but is version "
                 << version
                 << " where version 5 was expected."
@@ -224,7 +224,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
     LMI_ASSERT(i != elements.end());
     if("NumberOfClasses" != xml_lmi::get_name(*i))
         {
-        fatal_error()
+        alarum()
             << "XML node name is '"
             << xml_lmi::get_name(*i)
             << "' but '"
@@ -249,7 +249,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
             {
             if(1 != number_of_classes)
                 {
-                fatal_error()
+                alarum()
                     << "Class-default 'cell' element is empty, and there are "
                     << number_of_classes
                     << " classes where 1 was expected."
@@ -260,7 +260,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
             xml_lmi::get_attr(*i, "version", version);
             if(5 != version)
                 {
-                fatal_error()
+                alarum()
                     << "Class-default 'cell' element is empty, but is version "
                     << version
                     << " where version 5 was expected."
@@ -280,7 +280,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
         }
     if(class_parms_.size() != number_of_classes)
         {
-        fatal_error()
+        alarum()
             << "Number of classes read is "
             << class_parms_.size()
             << " but should have been "
@@ -296,7 +296,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
     LMI_ASSERT(i != elements.end());
     if("NumberOfCells" != xml_lmi::get_name(*i))
         {
-        fatal_error()
+        alarum()
             << "XML node name is '"
             << xml_lmi::get_name(*i)
             << "' but '"
@@ -333,7 +333,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
         }
     if(cell_parms_.size() != number_of_cells)
         {
-        fatal_error()
+        alarum()
             << "Number of individuals read is "
             << cell_parms_.size()
             << " but should have been "
@@ -347,7 +347,7 @@ void multiple_cell_document::parse_v0(xml_lmi::dom_parser 
const& parser)
     ++i;
     if(i != elements.end())
         {
-        fatal_error()
+        alarum()
             << "Read all data expected in XML document, "
             << "but more data remains."
             << LMI_FLUSH
diff --git a/mvc_controller.cpp b/mvc_controller.cpp
index 66cbd09..55cd48b 100644
--- a/mvc_controller.cpp
+++ b/mvc_controller.cpp
@@ -108,7 +108,7 @@ MvcController::MvcController
 
     if(!wxXmlResource::Get()->LoadDialog(this, parent, view_.MainDialogName()))
         {
-        fatal_error() << "Unable to load dialog." << LMI_FLUSH;
+        alarum() << "Unable to load dialog." << LMI_FLUSH;
         }
 
     
BookControl().ChangeSelection(last_selected_page[view_.ResourceFileName()]);
@@ -283,7 +283,7 @@ void MvcController::ConditionallyEnableItems
 
     if(control_is_enumerative && !datum)
         {
-        fatal_error()
+        alarum()
             << "View control '"
             << name
             << "' is of enumerative type '"
@@ -302,7 +302,7 @@ void MvcController::ConditionallyEnableItems
 
     if(!control_is_enumerative && datum)
         {
-        fatal_error()
+        alarum()
             << "Model datum '"
             << name
             << "' is of enumerative type '"
@@ -348,7 +348,7 @@ void MvcController::ConditionallyEnableItems
         }
     else
         {
-        fatal_error() << "Unexpected case." << LMI_FLUSH;
+        alarum() << "Unexpected case." << LMI_FLUSH;
         }
 }
 
@@ -357,12 +357,12 @@ wxWindow& MvcController::CurrentPage() const
     wxBookCtrlBase const& book = BookControl();
     if(wxNOT_FOUND == book.GetSelection())
         {
-        fatal_error() << "No page selected in notebook." << LMI_FLUSH;
+        alarum() << "No page selected in notebook." << LMI_FLUSH;
         }
     wxWindow* page = book.GetPage(book.GetSelection());
     if(!page)
         {
-        fatal_error() << "Selected notebook page is invalid." << LMI_FLUSH;
+        alarum() << "Selected notebook page is invalid." << LMI_FLUSH;
         }
     return *page;
 }
@@ -437,7 +437,7 @@ void MvcController::EnsureOptimalFocus()
             {
             EndModal(wxID_CANCEL);
             }
-        fatal_error()
+        alarum()
             << "Dialog cancelled because a disabled or null window ("
             << NameLabelId(f)
             << ") improperly had focus."
@@ -581,7 +581,7 @@ void MvcController::UpdateCircumscription
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Range limits not yet supported for control '"
             << name
             << "' of type '"
diff --git a/mvc_controller.tpp b/mvc_controller.tpp
index e418a37..45535ca 100644
--- a/mvc_controller.tpp
+++ b/mvc_controller.tpp
@@ -43,7 +43,7 @@ T const& MvcController::ModelReference(std::string const& 
name) const
     T const* p = ModelPointer<T>(name);
     if(!p)
         {
-        fatal_error()
+        alarum()
             << "Cannot convert Model datum '"
             << name
             << "' of type '"
@@ -75,7 +75,7 @@ T& MvcController::WindowFromXrcName(char const* name) const
     wxWindow* w = FindWindow(wxXmlResource::GetXRCID(name));
     if(!w)
         {
-        fatal_error()
+        alarum()
             << "Unable to find '"
             << name
             << "' in xml resources."
@@ -86,7 +86,7 @@ T& MvcController::WindowFromXrcName(char const* name) const
     T* t = dynamic_cast<T*>(w);
     if(!t)
         {
-        fatal_error()
+        alarum()
             << "Unable to convert '"
             << name
             << "' to type '"
diff --git a/mvc_model.cpp b/mvc_model.cpp
index 9bd23d8..b72075e 100644
--- a/mvc_model.cpp
+++ b/mvc_model.cpp
@@ -114,7 +114,7 @@ void MvcModel::Reconcile()
 
     if(!okay)
         {
-        fatal_error()
+        alarum()
             << "Unable to make Model consistent after "
             << maximum_iterations
             << " iterations."
diff --git a/path_utility.cpp b/path_utility.cpp
index 48d6634..6fe2210 100644
--- a/path_utility.cpp
+++ b/path_utility.cpp
@@ -281,7 +281,7 @@ fs::path unique_filepath
         filepath = filepath.branch_path() / basename;
         if(fs::exists(filepath))
             {
-            fatal_error()
+            alarum()
                 << "Cannot create unique file path from file name '"
                 << original_filepath
                 << "' with extension '"
@@ -307,7 +307,7 @@ namespace
 /// to be shown in the exception report.
 ///
 /// Although a std::invalid_argument exception might at first seem
-/// appropriate here, std::runtime_error (via fatal_error()) is chosen
+/// appropriate here, std::runtime_error (via alarum()) is chosen
 /// because the 'a_path' argument may be specified by users.
 ///
 /// Exceptions thrown from the boost filesystem library on path
@@ -332,31 +332,16 @@ void validate_path
         }
     catch(fs::filesystem_error const& e)
         {
-        fatal_error()
-            << context
-            << ": "
-            << e.what()
-            << LMI_FLUSH
-            ;
+        alarum() << context << ": " << e.what() << LMI_FLUSH;
         }
 
     if(path.empty())
         {
-        fatal_error()
-            << context
-            << " must not be empty."
-            << LMI_FLUSH
-            ;
+        alarum() << context << " must not be empty." << LMI_FLUSH;
         }
     if(!fs::exists(path))
         {
-        fatal_error()
-            << context
-            << " '"
-            << path
-            << "' not found."
-            << LMI_FLUSH
-            ;
+        alarum() << context << " '" << path << "' not found." << LMI_FLUSH;
         }
 }
 } // Unnamed namespace.
@@ -375,7 +360,7 @@ void validate_directory
     validate_path(directory, context);
     if(!fs::is_directory(directory))
         {
-        fatal_error()
+        alarum()
             << context
             << " '"
             << directory
@@ -399,7 +384,7 @@ void validate_filepath
     validate_path(filepath, context);
     if(fs::is_directory(filepath))
         {
-        fatal_error()
+        alarum()
             << context
             << " '"
             << filepath
diff --git a/policy_view.cpp b/policy_view.cpp
index 8424ceb..1242b5d 100644
--- a/policy_view.cpp
+++ b/policy_view.cpp
@@ -51,7 +51,7 @@ wxWindow* PolicyView::CreateChildWindow()
         );
     if(!main_panel)
         {
-        fatal_error() << "Unable to load xml resource." << LMI_FLUSH;
+        alarum() << "Unable to load xml resource." << LMI_FLUSH;
         }
 
     for(auto const& i : document().values())
@@ -64,7 +64,7 @@ wxWindow* PolicyView::CreateChildWindow()
             );
         if(!text_ctrl)
             {
-            fatal_error()
+            alarum()
                 << "Required text control '"
                 << i.first
                 << "' not found."
diff --git a/premium_tax.cpp b/premium_tax.cpp
index 5b0d70e..168db32 100644
--- a/premium_tax.cpp
+++ b/premium_tax.cpp
@@ -209,7 +209,7 @@ void premium_tax::test_consistency() const
 {
     if(varies_by_state_ && !load_rate_is_levy_rate_)
         {
-        fatal_error()
+        alarum()
             << "Premium-tax load varies by state, but differs"
             << " from premium-tax rates. Probably the database"
             << " is incorrect.\n"
@@ -221,7 +221,7 @@ void premium_tax::test_consistency() const
         {
         if(0.0 != tax_state_load_rate_)
             {
-            fatal_error()
+            alarum()
                 << "Premium-tax load is tiered in premium-tax state "
                 << mc_str(tax_state_)
                 << ", but the product database specifies a scalar load of "
@@ -237,7 +237,7 @@ void premium_tax::test_consistency() const
         {
         if(0.0 != domiciliary_load_rate_)
             {
-            fatal_error()
+            alarum()
                 << "Premium-tax load is tiered in state of domicile "
                 << mc_str(domicile_)
                 << ", but the product database specifies a scalar load of "
@@ -247,7 +247,7 @@ void premium_tax::test_consistency() const
                 << LMI_FLUSH
                 ;
             }
-        fatal_error()
+        alarum()
             << "Premium-tax load is tiered in state of domicile "
             << mc_str(domicile_)
             << ", but that case is not supported."
diff --git a/product_data.cpp b/product_data.cpp
index c547ce5..baf7a5b 100644
--- a/product_data.cpp
+++ b/product_data.cpp
@@ -71,7 +71,7 @@ template<> std::string value_cast<std::string>(glossed_string 
const& z)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Invalid function call. Context:"
             << '\n' << z.datum()
             << '\n' << z.gloss()
diff --git a/product_editor.cpp b/product_editor.cpp
index a579385..a6af8bb 100644
--- a/product_editor.cpp
+++ b/product_editor.cpp
@@ -134,10 +134,7 @@ wxTreeCtrl& TreeGridViewBase::tree() const
 {
     if(!tree_)
         {
-        fatal_error()
-            << "Tree control can't be null"
-            << LMI_FLUSH
-            ;
+        alarum() << "Tree control can't be null" << LMI_FLUSH;
         }
     return *tree_;
 }
@@ -146,10 +143,7 @@ MultiDimGrid& TreeGridViewBase::grid() const
 {
     if(!grid_)
         {
-        fatal_error()
-            << "Grid control can't be null"
-            << LMI_FLUSH
-            ;
+        alarum() << "Grid control can't be null" << LMI_FLUSH;
         }
     return *grid_;
 }
@@ -158,10 +152,7 @@ void TreeGridViewBase::set_grid_label_text(std::string 
const& label)
 {
     if(!grid_label_)
         {
-        fatal_error()
-            << "Grid control can't be null"
-            << LMI_FLUSH
-            ;
+        alarum() << "Grid control can't be null" << LMI_FLUSH;
         }
     grid_label_->SetLabel(label);
 }
diff --git a/progress_meter.cpp b/progress_meter.cpp
index eecaa1b..5da4536 100644
--- a/progress_meter.cpp
+++ b/progress_meter.cpp
@@ -44,7 +44,7 @@ std::shared_ptr<progress_meter> create_progress_meter
 {
     if(nullptr == progress_meter_creator)
         {
-        fatal_error() << "Function pointer not yet initialized." << LMI_FLUSH;
+        alarum() << "Function pointer not yet initialized." << LMI_FLUSH;
         }
 
     return progress_meter_creator(max_count, title, display_mode);
@@ -57,7 +57,7 @@ bool set_progress_meter_creator(progress_meter_creator_type f)
         // TODO ?? Use 'callback.hpp' instead, and consider whether
         // this message can ever actually be displayed--either in its
         // present form, or in the 'callback.hpp' equivalent.
-        fatal_error() << "Function pointer already initialized." << LMI_FLUSH;
+        alarum() << "Function pointer already initialized." << LMI_FLUSH;
         }
 
     progress_meter_creator = f;
@@ -88,11 +88,11 @@ bool progress_meter::reflect_progress()
 {
     if(max_count_ <= count_)
         {
-        fatal_error() << "Progress meter maximum count exceeded." << LMI_FLUSH;
+        alarum() << "Progress meter maximum count exceeded." << LMI_FLUSH;
         }
     if(was_cancelled_)
         {
-        fatal_error() << "Progress meter previously cancelled." << LMI_FLUSH;
+        alarum() << "Progress meter previously cancelled." << LMI_FLUSH;
         }
     ++count_;
     was_cancelled_ = !show_progress_message();
diff --git a/progress_meter_cli.cpp b/progress_meter_cli.cpp
index 5978fc6..5134e19 100644
--- a/progress_meter_cli.cpp
+++ b/progress_meter_cli.cpp
@@ -54,12 +54,7 @@ std::streambuf* 
select_streambuf(progress_meter::enum_display_mode display_mode)
             break;
         default:
             {
-            fatal_error()
-                << "Case "
-                << display_mode
-                << " not found."
-                << LMI_FLUSH
-                ;
+            alarum() << "Case " << display_mode << " not found." << LMI_FLUSH;
             }
         }
     return z;
diff --git a/rate_table.cpp b/rate_table.cpp
index df8dcc6..8155648 100644
--- a/rate_table.cpp
+++ b/rate_table.cpp
@@ -477,7 +477,7 @@ void writer::write_values
     // for its success, exceptionally, in order to detect the error a.s.a.p.
     if(!stream_write(os_, &little_endian_values[0], length))
         {
-        fatal_error() << "writing values failed" << std::flush;
+        alarum() << "writing values failed" << std::flush;
         }
 }
 
@@ -526,7 +526,7 @@ void writer::write(enum_soa_field field, 
boost::optional<std::string> const& ost
         std::string::size_type const length = ostr->size();
         if(std::numeric_limits<uint16_t>::max() < length)
             {
-            fatal_error()
+            alarum()
                 << "the value of the field '"
                 << soa_fields[field].name
                 << "' is too long to be represented in the SOA binary format"
@@ -747,7 +747,7 @@ boost::optional<field_and_value> parse_field_and_value
                 {
                 if(pos_colon + 1 != line.length())
                     {
-                    fatal_error()
+                    alarum()
                         << "value not allowed after '" << name << ":'"
                         << location_info(line_num)
                         << std::flush
@@ -758,7 +758,7 @@ boost::optional<field_and_value> parse_field_and_value
                 {
                 if(pos_colon + 1 == line.length())
                     {
-                    fatal_error()
+                    alarum()
                         << "value expected after '" << name << ":'"
                         << location_info(line_num, pos_colon + 1)
                         << std::flush
@@ -767,7 +767,7 @@ boost::optional<field_and_value> parse_field_and_value
 
                 if(line[pos_colon + 1] != ' ')
                     {
-                    fatal_error()
+                    alarum()
                         << "space expected after '" << name << ":'"
                         << location_info(line_num, pos_colon + 1)
                         << std::flush
@@ -1047,7 +1047,7 @@ void throw_if_duplicate_record
 {
     if(do_throw)
         {
-        fatal_error()
+        alarum()
             << "duplicate occurrence of the field '"
             << soa_fields[field].name
             << "'"
@@ -1066,7 +1066,7 @@ void throw_if_unexpected_length
 {
     if(length != expected_length)
         {
-        fatal_error()
+        alarum()
             << "unexpected length " << length
             << " for the field '"
             << soa_fields[field].name
@@ -1084,7 +1084,7 @@ void throw_if_missing_field(boost::optional<T> const& o, 
enum_soa_field field)
 {
     if(!o)
         {
-        fatal_error()
+        alarum()
             << "required field '"
             << soa_fields[field].name
             << "' was not specified"
@@ -1108,7 +1108,7 @@ void table_impl::read_string
     str.resize(length);
     if(!stream_read(ifs, &str[0], length))
         {
-        fatal_error()
+        alarum()
             << "failed to read all " << length << " bytes of the field '"
             << soa_fields[field].name
             << "'"
@@ -1125,7 +1125,7 @@ T table_impl::do_read_number(char const* name, 
std::istream& ifs)
     T num;
     if(!stream_read(ifs, &num, sizeof(T)))
         {
-        fatal_error() << "failed to read field '" << name << "'" << std::flush;
+        alarum() << "failed to read field '" << name << "'" << std::flush;
         }
 
     return swap_bytes_if_big_endian(num);
@@ -1148,7 +1148,7 @@ void table_impl::read_type(std::istream& ifs, uint16_t 
length)
             return;
         }
 
-    fatal_error() << "unknown table type '" << type << "'" << std::flush;
+    alarum() << "unknown table type '" << type << "'" << std::flush;
 }
 
 template<typename T>
@@ -1175,7 +1175,7 @@ void table_impl::read_number_before_values
 {
     if(!values_.empty())
         {
-        fatal_error()
+        alarum()
             << "field '"
             << soa_fields[field].name
             << "' must occur before the values"
@@ -1195,7 +1195,7 @@ unsigned table_impl::get_expected_number_of_values() const
     // fields determining this as a side effect.
     if(*max_age_ < *min_age_)
         {
-        fatal_error()
+        alarum()
             << "minimum age " << *min_age_
             << " cannot be greater than the maximum age " << *max_age_
             << std::flush
@@ -1220,7 +1220,7 @@ unsigned table_impl::get_expected_number_of_values() const
         // in integer overflow below if it were allowed.
         if(num_values < *select_period_)
             {
-            fatal_error()
+            alarum()
                 << "select period " << *select_period_
                 << " is too big for the age range "
                 << *min_age_ << ".." << *max_age_
@@ -1249,7 +1249,7 @@ unsigned table_impl::get_expected_number_of_values() const
 
         if(std::numeric_limits<unsigned>::max() - num_values < select_range)
             {
-            fatal_error()
+            alarum()
                 << "too many values in the table with maximum age " << 
*max_age_
                 << ", select period " << *select_period_
                 << " and maximum select age " << effective_max_select
@@ -1278,7 +1278,7 @@ void table_impl::read_values(std::istream& ifs, uint16_t 
/* length */)
     values_.resize(num_values);
     if(!stream_read(ifs, &values_[0], num_values*sizeof(double)))
         {
-        fatal_error() << "failed to read the values" << std::flush;
+        alarum() << "failed to read the values" << std::flush;
         }
 
     for(auto& v : values_)
@@ -1300,7 +1300,7 @@ std::string* table_impl::parse_string
     // some historical files have put commentary in table name instead.
     if(value.empty() && e_field_comments != field)
         {
-        fatal_error()
+        alarum()
             << "non-empty value must be specified for the field '"
             << soa_fields[field].name
             << "'"
@@ -1324,7 +1324,7 @@ unsigned long table_impl::do_parse_number
     auto const res = strict_parse_number(value.c_str());
     if(!res.end || *res.end != '\0')
         {
-        fatal_error()
+        alarum()
             << "value for numeric field '"
             << soa_fields[field].name
             << "' is not a number"
@@ -1335,7 +1335,7 @@ unsigned long table_impl::do_parse_number
 
     if(max_num < res.num)
         {
-        fatal_error()
+        alarum()
             << "value for numeric field '"
             << soa_fields[field].name
             << "' is out of range (maximum allowed is "
@@ -1383,7 +1383,7 @@ void table_impl::parse_table_type
         }
     else
         {
-        fatal_error()
+        alarum()
             << "invalid table type value '" << value << "'"
             << location_info(line_num)
             << " (\"" << table_type_as_string(table_type::aggregate) << "\", "
@@ -1403,7 +1403,7 @@ void table_impl::parse_select_header(std::istream& is, 
int& line_num) const
     std::string line;
     if(!std::getline(is, line))
         {
-        fatal_error()
+        alarum()
             << "header expected for a select table"
             << location_info(line_num)
             << std::flush
@@ -1416,7 +1416,7 @@ void table_impl::parse_select_header(std::istream& is, 
int& line_num) const
         {
         if(actual != expected)
             {
-            fatal_error()
+            alarum()
                 << "expected duration " << expected
                 << " and not " << actual
                 << " in the select table header" << location_info(line_num)
@@ -1432,7 +1432,7 @@ void table_impl::parse_select_header(std::istream& is, 
int& line_num) const
 
     if(actual != *select_period_)
         {
-        fatal_error()
+        alarum()
             << "expected " << *select_period_
             << " duration labels and not " << actual
             << " in the select table header" << location_info(line_num)
@@ -1444,7 +1444,7 @@ void table_impl::parse_select_header(std::istream& is, 
int& line_num) const
     iss >> header;
     if(!iss)
         {
-        fatal_error()
+        alarum()
             << "expected the ultimate column label \""
             << text_format::ultimate_header << "\""
             << " in the select table header" << location_info(line_num)
@@ -1454,7 +1454,7 @@ void table_impl::parse_select_header(std::istream& is, 
int& line_num) const
 
     if(header != text_format::ultimate_header)
         {
-        fatal_error()
+        alarum()
             << "expected the ultimate column label \""
             << text_format::ultimate_header << "\""
             << " and not \"" << header << "\""
@@ -1479,7 +1479,7 @@ uint16_t table_impl::parse_age
         {
         if(start_num - current == age_width)
             {
-            fatal_error()
+            alarum()
                 << "at most " << age_width - 1 << " spaces allowed"
                 << location_info(line_num, current - start + 1)
                 << std::flush
@@ -1492,7 +1492,7 @@ uint16_t table_impl::parse_age
     auto const res_age = strict_parse_number(start_num);
     if(!res_age.end || (res_age.end - current != age_width))
         {
-        fatal_error()
+        alarum()
             << "expected a number with "
             << age_width - (start_num - current) << " digits"
             << location_info(line_num, start_num - start + 1)
@@ -1525,7 +1525,7 @@ double table_impl::parse_single_value
         ;
     if(*current != ' ')
         {
-        fatal_error()
+        alarum()
             << "expected a space"
             << location_info(line_num, current - start + 1)
             << std::flush
@@ -1538,7 +1538,7 @@ double table_impl::parse_single_value
         }
     if(num_spaces_allowed < num_spaces)
         {
-        fatal_error()
+        alarum()
             << "too many spaces"
             << location_info(line_num, current - start + 1)
             << " (at most " << num_spaces_allowed << " allowed here)"
@@ -1551,7 +1551,7 @@ double table_impl::parse_single_value
     auto const res_int_part = strict_parse_number(current);
     if(!res_int_part.end)
         {
-        fatal_error()
+        alarum()
             << "expected a valid integer part"
             << location_info(line_num, current - start + 1)
             << std::flush
@@ -1567,7 +1567,7 @@ double table_impl::parse_single_value
 
     if(*res_int_part.end != '.')
         {
-        fatal_error()
+        alarum()
             << "expected decimal point"
             << location_info(line_num, res_int_part.end - start + 1)
             << std::flush
@@ -1577,7 +1577,7 @@ double table_impl::parse_single_value
     auto const res_frac_part = strict_parse_number(res_int_part.end + 1);
     if(!res_frac_part.end)
         {
-        fatal_error()
+        alarum()
             << "expected a valid fractional part"
             << location_info(line_num, res_frac_part.end - start + 1)
             << std::flush
@@ -1586,7 +1586,7 @@ double table_impl::parse_single_value
 
     if(res_frac_part.end - res_int_part.end - 1 != *num_decimals_)
         {
-        fatal_error()
+        alarum()
             << "expected " << *num_decimals_ << " decimal digits, not "
             << res_frac_part.end - res_int_part.end - 1
             << " in the value"
@@ -1609,7 +1609,7 @@ void table_impl::skip_spaces
 {
     if(std::strncmp(current, std::string(num_spaces, ' ').c_str(), num_spaces) 
!= 0)
         {
-        fatal_error()
+        alarum()
             << "expected " << num_spaces << " spaces"
             << location_info(line_num, current - start + 1)
             << std::flush
@@ -1648,7 +1648,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
 
     if(!num_decimals_)
         {
-        fatal_error()
+        alarum()
             << "the '" << soa_fields[e_field_num_decimals].name << "' field "
             << "must be specified before the table values"
             << location_info(line_num)
@@ -1658,7 +1658,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
 
     if(!type_)
         {
-        fatal_error()
+        alarum()
             << "table type must occur before its values"
             << location_info(line_num)
             << std::flush
@@ -1691,7 +1691,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
         if(!std::getline(is, line))
             {
             // Complain about premature input end.
-            fatal_error()
+            alarum()
                 << "table values for age " << age
                 << " are missing" << location_info(line_num)
                 << std::flush
@@ -1707,7 +1707,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
             {
             // Distinguish select age at the beginning of the line from the
             // ultimate age on the right side of the table.
-            fatal_error()
+            alarum()
                 << "incorrect "
                 << (is_select_table ? "select " : "")
                 << "age value " << actual_age
@@ -1754,7 +1754,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
             auto const ultimate_age = parse_age(start, current, line_num);
             if(ultimate_age != expected_age)
                 {
-                fatal_error()
+                alarum()
                     << "incorrect ultimate age value " << ultimate_age
                     << location_info(line_num)
                     << " (" << expected_age << " expected)"
@@ -1765,7 +1765,7 @@ void table_impl::parse_values(std::istream& is, int& 
line_num)
 
         if(current - start < static_cast<int>(line.length()))
             {
-            fatal_error()
+            alarum()
                 << "unexpected characters \"" << current << "\""
                 << location_info(line_num, current - start + 1)
                 << std::flush
@@ -1800,7 +1800,7 @@ void table_impl::validate()
         // the values.
         if(values_.empty())
             {
-            fatal_error() << "no values defined" << std::flush;
+            alarum() << "no values defined" << std::flush;
             }
 
         // Validate the type and check that the select period has or hasn't
@@ -1811,7 +1811,7 @@ void table_impl::validate()
             case table_type::duration:
                 if(get_value_or(select_period_, 0))
                     {
-                    fatal_error()
+                    alarum()
                         << "select period cannot be specified for a table "
                         << "of type '" << table_type_as_string(*type_) << "'"
                         << std::flush
@@ -1821,7 +1821,7 @@ void table_impl::validate()
                   && *max_select_age_ != *max_age_
                   )
                     {
-                    fatal_error()
+                    alarum()
                         << "maximum select age " << *max_select_age_
                         << " different from the maximum age " << *max_age_
                         << " cannot be specified for a table of type '"
@@ -1834,7 +1834,7 @@ void table_impl::validate()
             case table_type::select:
                 if(!get_value_or(select_period_, 0))
                     {
-                    fatal_error()
+                    alarum()
                         << "select period must be specified "
                         << "for a select and ultimate table"
                         << std::flush
@@ -1842,7 +1842,7 @@ void table_impl::validate()
                     }
                 if(!get_value_or(max_select_age_, 0))
                     {
-                    fatal_error()
+                    alarum()
                         << "maximum select age must be specified "
                         << "for a select and ultimate table"
                         << std::flush
@@ -1853,7 +1853,7 @@ void table_impl::validate()
 
         if(!num_decimals_)
             {
-            fatal_error() << "Number of decimals not specified." << LMI_FLUSH;
+            alarum() << "Number of decimals not specified." << LMI_FLUSH;
             }
 
         uint16_t putative_num_decimals = *num_decimals_;
@@ -1886,7 +1886,7 @@ void table_impl::validate()
             {
             if(*hash_value_ != correct_hash_value)
                 {
-                fatal_error()
+                alarum()
                     << "hash value " << *hash_value_ << " doesn't match "
                     << "the computed hash value " << correct_hash_value
                     << std::flush
@@ -1900,7 +1900,7 @@ void table_impl::validate()
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "bad data for table " << *number_ << ": "
             << e.what()
             << std::flush
@@ -1913,7 +1913,7 @@ void table_impl::read_from_binary(std::istream& ifs, 
uint32_t offset)
     ifs.seekg(offset, std::ios::beg);
     if(!ifs)
         {
-        fatal_error() << "seek error" << std::flush;
+        alarum() << "seek error" << std::flush;
         }
 
     for(;;)
@@ -1992,7 +1992,7 @@ void table_impl::read_from_binary(std::istream& ifs, 
uint32_t offset)
                 read_number(hash_value_, e_field_hash_value, ifs, length);
                 break;
             default:
-                fatal_error() << "unknown field type " << record_type << 
std::flush;
+                alarum() << "unknown field type " << record_type << std::flush;
             }
         }
 }
@@ -2041,7 +2041,7 @@ void table_impl::read_from_text(std::istream& is)
                 {
                 if(line.find_first_not_of(whitespace) != std::string::npos)
                     {
-                    fatal_error()
+                    alarum()
                         << "blank line " << blank_line_num << " "
                         << "cannot appear in the middle of the input "
                         << "and be followed by non-blank line " << line_num
@@ -2062,7 +2062,7 @@ void table_impl::read_from_text(std::istream& is)
             // Only one field can appear after the table values.
             if(!values_.empty() && field != e_field_hash_value)
                 {
-                fatal_error()
+                alarum()
                     << "field '" << soa_fields[field].name << "' "
                     << "is not allowed after the table values"
                     << location_info(line_num)
@@ -2130,7 +2130,7 @@ void table_impl::read_from_text(std::istream& is)
                 case e_field_hash_value:
                     if(values_.empty())
                         {
-                        fatal_error()
+                        alarum()
                             << "'" << soa_fields[field].name << "' field "
                             << "is only allowed after the table values and not 
"
                             << location_info(line_num)
@@ -2147,7 +2147,7 @@ void table_impl::read_from_text(std::istream& is)
             // Must be a continuation of the previous line.
             if(!last_string)
                 {
-                fatal_error()
+                alarum()
                     << "expected a field name followed by a colon"
                     << location_info(line_num)
                     << std::flush
@@ -2203,7 +2203,7 @@ void table_impl::do_write(std::ostream& os) const
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "saving table " << *number_ << "failed: " << e.what()
             << std::flush
             ;
@@ -2269,7 +2269,7 @@ unsigned long table_impl::compute_hash_value() const
 table table::read_from_text(fs::path const& file)
 {
     fs::ifstream ifs(file, ios_in_binary());
-    if(!ifs) fatal_error() << "Unable to open '" << file << "'." << LMI_FLUSH;
+    if(!ifs) alarum() << "Unable to open '" << file << "'." << LMI_FLUSH;
 
     try
         {
@@ -2277,7 +2277,7 @@ table table::read_from_text(fs::path const& file)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error reading table from file '" << file << "': "
             << e.what()
             << "."
@@ -2296,7 +2296,7 @@ table table::read_from_text(std::string const& text)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error reading table from string: "
             << e.what()
             << "."
@@ -2309,7 +2309,7 @@ table table::read_from_text(std::string const& text)
 void table::save_as_text(fs::path const& file) const
 {
     fs::ofstream ofs(file, ios_out_trunc_binary());
-    if(!ofs) fatal_error() << "Unable to open '" << file << "'." << LMI_FLUSH;
+    if(!ofs) alarum() << "Unable to open '" << file << "'." << LMI_FLUSH;
     impl_->write_as_text(ofs);
 }
 
@@ -2483,7 +2483,7 @@ database_impl::database_impl(fs::path const& path)
 
     fs::path const index_path = get_index_path(path);
     fs::ifstream ifs(index_path, ios_in_binary());
-    if(!ifs) fatal_error() << "Unable to open '" << index_path << "'." << 
LMI_FLUSH;
+    if(!ifs) alarum() << "Unable to open '" << index_path << "'." << LMI_FLUSH;
     read_index(ifs);
 
     // Open the database file right now to ensure that we can do it, even if we
@@ -2491,7 +2491,7 @@ database_impl::database_impl(fs::path const& path)
     // it wouldn't be a useful optimization.
     fs::path const data_path = get_data_path(path);
     auto const pifs = std::make_shared<fs::ifstream>(data_path, 
ios_in_binary());
-    if(!*pifs) fatal_error() << "Unable to open '" << data_path << "'." << 
LMI_FLUSH;
+    if(!*pifs) alarum() << "Unable to open '" << data_path << "'." << 
LMI_FLUSH;
     data_is_ = pifs;
 }
 
@@ -2564,7 +2564,7 @@ void database_impl::read_index(std::istream& index_is)
                 break;
                 }
 
-            fatal_error()
+            alarum()
                 << "error reading entry " << index_.size()
                 << " from the database index"
                 << std::flush
@@ -2579,7 +2579,7 @@ void database_impl::read_index(std::istream& index_is)
         // Check that the cast to int below is safe.
         if(static_cast<unsigned>(std::numeric_limits<int>::max()) <= number)
             {
-            fatal_error()
+            alarum()
                 << "database index is corrupt: "
                 << "table number " << number << " is out of range"
                 << std::flush
@@ -2588,7 +2588,7 @@ void database_impl::read_index(std::istream& index_is)
 
         if(!add_index_entry(table::Number(static_cast<int>(number)), offset))
             {
-            fatal_error()
+            alarum()
                 << "database index is corrupt: "
                 << "duplicate entries for the table number " << number
                 << std::flush
@@ -2622,7 +2622,7 @@ shared_ptr<table_impl> database_impl::do_get_table_impl
             }
         catch(std::runtime_error const& e)
             {
-            fatal_error()
+            alarum()
                 << "error reading table " << entry.number_
                 << " from the offset " << entry.offset_
                 << " in the database '" << path_ << "': " << e.what()
@@ -2632,7 +2632,7 @@ shared_ptr<table_impl> database_impl::do_get_table_impl
 
         if(entry.table_->number() != entry.number_)
             {
-            fatal_error()
+            alarum()
                 << "database '" << path_ << "' is corrupt: "
                 << "table number " << entry.table_->number()
                 << " is inconsistent with its number in the index ("
@@ -2855,7 +2855,7 @@ void database_impl::save(fs::path const& path)
 
             database_.cleanup_temp();
 
-            fatal_error() << error_stream.str() << std::flush;
+            alarum() << error_stream.str() << std::flush;
             }
 
       private:
@@ -2880,7 +2880,7 @@ void database_impl::save(fs::path const& path)
                 ,description_(description)
             {
             ofs_.open(temp_path_, ios_out_trunc_binary());
-            if(!ofs_) fatal_error() << "Unable to open '" << temp_path_ << 
"'." << LMI_FLUSH;
+            if(!ofs_) alarum() << "Unable to open '" << temp_path_ << "'." << 
LMI_FLUSH;
             }
 
             void close()
@@ -2888,7 +2888,7 @@ void database_impl::save(fs::path const& path)
                 ofs_.close();
                 if(!ofs_)
                     {
-                    fatal_error()
+                    alarum()
                         << "failed to close the output " << description_
                         << " file \"" << temp_path_ << "\""
                         << std::flush
@@ -2959,7 +2959,7 @@ void database_impl::save(std::ostream& index_os, 
std::ostream& data_os)
         uint32_t const offset32 = static_cast<uint32_t>(offset);
         if(static_cast<std::streamoff>(offset32) != offset)
             {
-            fatal_error()
+            alarum()
                 << "database is too large to be stored in SOA v3 format."
                 << std::flush
                 ;
@@ -3011,7 +3011,7 @@ try
 }
 catch(std::runtime_error const& e)
 {
-    fatal_error()
+    alarum()
         << "Error reading database from '" << path << "': "
         << e.what()
         << "."
@@ -3029,7 +3029,7 @@ try
 }
 catch(std::runtime_error const& e)
 {
-    fatal_error()
+    alarum()
         << "Error reading database: "
         << e.what()
         << "."
@@ -3055,7 +3055,7 @@ table database::get_nth_table(int idx) const
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error getting table at index " << idx << ": "
             << e.what()
             << "."
@@ -3073,7 +3073,7 @@ table database::find_table(table::Number number) const
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error getting table with number " << number << ": "
             << e.what()
             << "."
@@ -3091,7 +3091,7 @@ void database::append_table(table const& table)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error appending table number " << table.number()
             << " to the database: "
             << e.what()
@@ -3109,7 +3109,7 @@ void database::add_or_replace_table(table const& table)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error adding table number " << table.number() << ": "
             << e.what()
             << "."
@@ -3126,7 +3126,7 @@ void database::delete_table(table::Number number)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error deleting table number " << number << ": "
             << e.what()
             << "."
@@ -3143,7 +3143,7 @@ void database::save(fs::path const& path)
         }
     catch(std::runtime_error const& e)
         {
-        fatal_error()
+        alarum()
             << "Error saving database to '" << path << "': "
             << e.what()
             << "."
@@ -3162,7 +3162,7 @@ void database::save(std::ostream& index_os, std::ostream& 
data_os)
         {
         // We can't really provide any extra information here, but still do it
         // just for consistency with save() above.
-        fatal_error()
+        alarum()
             << "Error saving database to: "
             << e.what()
             << "."
diff --git a/rate_table_tool.cpp b/rate_table_tool.cpp
index d1c2a1d..a6b2cdb 100644
--- a/rate_table_tool.cpp
+++ b/rate_table_tool.cpp
@@ -242,7 +242,7 @@ void rename_tables
     std::ifstream ifs(filename_of_table_names.string().c_str());
     if(!ifs)
         {
-        fatal_error()
+        alarum()
             << "File with the new table names \"" << filename_of_table_names
             << "\" couldn't be opened."
             << std::flush
@@ -296,7 +296,7 @@ void rename_tables
 
         if(!error.empty())
             {
-            fatal_error()
+            alarum()
                 << "Error in new table names file \"" << 
filename_of_table_names
                 << "\": " << error << " at line " << line_num << "."
                 << std::flush
@@ -344,9 +344,7 @@ int verify(fs::path const& database_filename)
             auto const new_text = new_table.save_as_text();
             if(new_text != orig_text)
                 {
-                // This is not really fatal, it is only used here to throw an
-                // exception in a convenient way.
-                fatal_error()
+                alarum()
                     << "After loading and saving the original table '\n"
                     << orig_text
                     << "' became '\n"
@@ -357,9 +355,7 @@ int verify(fs::path const& database_filename)
                 }
             if(new_table != orig_table)
                 {
-                // This is not really fatal, it is only used here to throw an
-                // exception in a convenient way.
-                fatal_error()
+                alarum()
                     << "After loading and saving the original table \n"
                     << "binary contents differed.\n"
                     << LMI_FLUSH
diff --git a/rounding_rules.cpp b/rounding_rules.cpp
index 434629b..cbb35c8 100644
--- a/rounding_rules.cpp
+++ b/rounding_rules.cpp
@@ -67,7 +67,7 @@ template<> struct xml_io<rounding_parameters>
 
 template<> std::string value_cast<std::string>(rounding_parameters const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
@@ -79,7 +79,7 @@ template<> std::string 
value_cast<std::string>(rounding_parameters const&)
 
 template<> rounding_parameters value_cast<rounding_parameters>(std::string 
const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
diff --git a/rounding_view.cpp b/rounding_view.cpp
index 9fb5bd7..3e7e069 100644
--- a/rounding_view.cpp
+++ b/rounding_view.cpp
@@ -51,7 +51,7 @@ wxWindow* RoundingView::CreateChildWindow()
         );
     if(!main_panel)
         {
-        fatal_error() << "Unable to load xml resource." << LMI_FLUSH;
+        alarum() << "Unable to load xml resource." << LMI_FLUSH;
         }
 
     for(auto const& i : document().values())
@@ -64,7 +64,7 @@ wxWindow* RoundingView::CreateChildWindow()
             );
         if(!control)
             {
-            fatal_error()
+            alarum()
                 << "Required text control '"
                 << i.first
                 << "' not found."
diff --git a/sigfpe.cpp b/sigfpe.cpp
index 4741d9d..422efbc 100644
--- a/sigfpe.cpp
+++ b/sigfpe.cpp
@@ -45,7 +45,7 @@ void floating_point_error_handler(int)
 
     if(SIG_ERR == std::signal(SIGFPE, floating_point_error_handler))
         {
-        fatal_error()
+        alarum()
             << "Cannot reinstall floating point error signal handler."
             << LMI_FLUSH
             ;
diff --git a/single_cell_document.cpp b/single_cell_document.cpp
index 5a76579..e0fba3a 100644
--- a/single_cell_document.cpp
+++ b/single_cell_document.cpp
@@ -108,7 +108,7 @@ void single_cell_document::parse(xml_lmi::dom_parser const& 
parser)
 
     if(class_version() < file_version)
         {
-        fatal_error() << "Incompatible file version." << LMI_FLUSH;
+        alarum() << "Incompatible file version." << LMI_FLUSH;
         }
 
     if(data_source_is_external(parser.document()))
diff --git a/skeleton.cpp b/skeleton.cpp
index e65d734..0ecf514 100644
--- a/skeleton.cpp
+++ b/skeleton.cpp
@@ -107,8 +107,6 @@
 
 namespace
 {
-// Load the XRC file with the given base name from the data directory and call
-// fatal_error() if loading it failed.
 void load_xrc_file_from_data_directory
     (wxXmlResource& xml_resources
     ,char const* xrc_filename
@@ -120,7 +118,7 @@ void load_xrc_file_from_data_directory
     if(!xml_resources.Load(AddDataDir(xrc_filename)))
 #endif // !wxCHECK_VERSION(2,9,0)
         {
-        fatal_error() << "Unable to load xml resources." << LMI_FLUSH;
+        alarum() << "Unable to load xml resources." << LMI_FLUSH;
         }
 }
 } // Unnamed namespace.
@@ -142,13 +140,13 @@ BEGIN_EVENT_TABLE(Skeleton, wxApp)
     EVT_MENU(XRCID("test_app_status_alert"           
),Skeleton::UponTestAppStatus                )
     EVT_MENU(XRCID("test_app_warning_alert"          
),Skeleton::UponTestAppWarning               )
     EVT_MENU(XRCID("test_app_hobsons_choice_alert"   
),Skeleton::UponTestAppHobsons               )
-    EVT_MENU(XRCID("test_app_fatal_error_alert"      
),Skeleton::UponTestAppFatal                 )
+    EVT_MENU(XRCID("test_app_alarum_alert"           
),Skeleton::UponTestAppFatal                 )
     EVT_MENU(XRCID("test_app_standard_exception"     
),Skeleton::UponTestAppStandardException     )
     EVT_MENU(XRCID("test_app_arbitrary_exception"    
),Skeleton::UponTestAppArbitraryException    )
     EVT_MENU(XRCID("test_lib_status_alert"           
),Skeleton::UponTestLibStatus                )
     EVT_MENU(XRCID("test_lib_warning_alert"          
),Skeleton::UponTestLibWarning               )
     EVT_MENU(XRCID("test_lib_hobsons_choice_alert"   
),Skeleton::UponTestLibHobsons               )
-    EVT_MENU(XRCID("test_lib_fatal_error_alert"      
),Skeleton::UponTestLibFatal                 )
+    EVT_MENU(XRCID("test_lib_alarum_alert"           
),Skeleton::UponTestLibFatal                 )
     EVT_MENU(XRCID("test_lib_standard_exception"     
),Skeleton::UponTestLibStandardException     )
     EVT_MENU(XRCID("test_lib_arbitrary_exception"    
),Skeleton::UponTestLibArbitraryException    )
     EVT_MENU(XRCID("test_lib_catastrophe_report"     
),Skeleton::UponTestLibCatastropheReport     )
@@ -447,7 +445,7 @@ void Skeleton::InitMenuBar()
     wxMenuBar* menu_bar = wxXmlResource::Get()->LoadMenuBar("main_menu");
     if(!menu_bar)
         {
-        fatal_error() << "Unable to create menubar." << LMI_FLUSH;
+        alarum() << "Unable to create menubar." << LMI_FLUSH;
         }
     else
         {
@@ -464,7 +462,7 @@ void Skeleton::InitToolBar()
     wxToolBar* tool_bar = wxXmlResource::Get()->LoadToolBar(frame_, "toolbar");
     if(!tool_bar)
         {
-        fatal_error() << "Unable to create toolbar." << LMI_FLUSH;
+        alarum() << "Unable to create toolbar." << LMI_FLUSH;
         }
     frame_->SetToolBar(tool_bar);
 }
@@ -490,7 +488,7 @@ void Skeleton::UponEditDefaultCell(wxCommandEvent&)
 
     if(p.empty() || !fs::exists(p) || fs::is_directory(p))
         {
-        fatal_error()
+        alarum()
             << "The default input file, '"
             << p
             << "', could not be read.\n\n"
@@ -544,20 +542,20 @@ void Skeleton::UponHelp(wxCommandEvent&)
     }
     if(!r)
         {
-        fatal_error()
+        alarum()
             << "Unable to open"
             << "\n    " << s
             << "\nin default browser."
             ;
         if(canonical_url != s)
             {
-            fatal_error()
+            alarum()
                 << '\n'
                 << "\nThe user manual can be read online here:"
                 << "\n    " << canonical_url
                 ;
             }
-        fatal_error() << std::flush;
+        alarum() << std::flush;
         }
 
     fenv_validate(e_fenv_indulge_0x027f);
@@ -961,7 +959,7 @@ void Skeleton::UponTestAppHobsons(wxCommandEvent&)
 
 void Skeleton::UponTestAppFatal(wxCommandEvent&)
 {
-    fatal_error()    << "Test fatal_error() ."    << LMI_FLUSH;
+    alarum()         << "Test alarum() ."         << LMI_FLUSH;
 }
 
 void Skeleton::UponTestAppStandardException(wxCommandEvent&)
@@ -991,7 +989,7 @@ void Skeleton::UponTestLibHobsons(wxCommandEvent&)
 
 void Skeleton::UponTestLibFatal(wxCommandEvent&)
 {
-    test_fatal_error();
+    test_alarum();
 }
 
 void Skeleton::UponTestLibStandardException(wxCommandEvent&)
diff --git a/solve.cpp b/solve.cpp
index d22973e..a1acc3c 100644
--- a/solve.cpp
+++ b/solve.cpp
@@ -124,7 +124,7 @@ double SolveTest()
 // fall through...
                 default:
                     {
-                    fatal_error()
+                    alarum()
                         << "Case "
                         << ThatSolveTarget
                         << " not found."
@@ -142,7 +142,7 @@ double SolveTest()
         case mce_solve_for_tax_basis: // Fall through.
         case mce_solve_for_non_mec:
             {
-            fatal_error() << "Not implemented.";
+            alarum() << "Not implemented.";
             }
             break;
         throw "Unreachable--silences a compiler diagnostic.";
@@ -307,7 +307,7 @@ double AccountValue::Solve()
             break;
         default:
             {
-            fatal_error()
+            alarum()
                 << "Case "
                 << yare_input_.SolveType
                 << " not found."
diff --git a/stratified_charges.cpp b/stratified_charges.cpp
index c551833..f284287 100644
--- a/stratified_charges.cpp
+++ b/stratified_charges.cpp
@@ -64,7 +64,7 @@ namespace xml_serialize
 
 template<> std::string value_cast<std::string>(stratified_entity const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
@@ -76,7 +76,7 @@ template<> std::string 
value_cast<std::string>(stratified_entity const&)
 
 template<> stratified_entity value_cast<stratified_entity>(std::string const&)
 {
-    fatal_error() << "Invalid function call." << LMI_FLUSH;
+    alarum() << "Invalid function call." << LMI_FLUSH;
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
@@ -284,7 +284,7 @@ double stratified_charges::stratified_sepacct_load
             // break;
         case mce_gen_mdpt:
             {
-            fatal_error()
+            alarum()
                 << "Dynamic separate-account load not supported with "
                 << "midpoint expense basis, because variable products "
                 << "are not subject to the illustration reg."
@@ -294,7 +294,7 @@ double stratified_charges::stratified_sepacct_load
             break;
         default:
             {
-            fatal_error() << "Case '" << basis << "' not found." << LMI_FLUSH;
+            alarum() << "Case '" << basis << "' not found." << LMI_FLUSH;
             }
         }
     throw "Unreachable--silences a compiler diagnostic.";
@@ -356,7 +356,7 @@ double stratified_charges::tiered_m_and_e(mcenum_gen_basis 
basis, double assets)
             // break;
         case mce_gen_mdpt:
             {
-            fatal_error()
+            alarum()
                 << "Dynamic separate-account M&E not supported with "
                 << "midpoint expense basis, because variable products "
                 << "are not subject to the illustration reg."
@@ -366,7 +366,7 @@ double stratified_charges::tiered_m_and_e(mcenum_gen_basis 
basis, double assets)
             break;
         default:
             {
-            fatal_error() << "Case '" << basis << "' not found." << LMI_FLUSH;
+            alarum() << "Case '" << basis << "' not found." << LMI_FLUSH;
             }
         }
     throw "Unreachable--silences a compiler diagnostic.";
diff --git a/system_command_non_wx.cpp b/system_command_non_wx.cpp
index 26b05ef..0dec727 100644
--- a/system_command_non_wx.cpp
+++ b/system_command_non_wx.cpp
@@ -46,7 +46,7 @@ void concrete_system_command(std::string const& command_line)
     int exit_code = std::system(command_line.c_str());
     if(EXIT_SUCCESS != exit_code)
         {
-        fatal_error()
+        alarum()
             << "Exit code "
             << exit_code
             << " from command '"
@@ -91,7 +91,7 @@ void concrete_system_command(std::string const& command_line)
 
     if(0 != exit_code)
         {
-        fatal_error()
+        alarum()
             << "Exit code "
             << exit_code
             << " from command '"
diff --git a/system_command_wx.cpp b/system_command_wx.cpp
index 264378d..1e384cd 100644
--- a/system_command_wx.cpp
+++ b/system_command_wx.cpp
@@ -102,7 +102,7 @@ void concrete_system_command(std::string const& 
command_line)
         }
     else if(-1L == exit_code)
         {
-        fatal_error()
+        alarum()
             << "Command '"
             << command_line
             << "' not recognized."
@@ -111,16 +111,16 @@ void concrete_system_command(std::string const& 
command_line)
         }
     else
         {
-        fatal_error()
+        alarum()
             << "Exit code "
             << exit_code
             << " from command '"
             << command_line
             << "'.\n"
             ;
-        assemble_console_lines(fatal_error(), output, "Output:");
-        assemble_console_lines(fatal_error(), errors, "Errors:");
-        fatal_error() << std::flush;
+        assemble_console_lines(alarum(), output, "Output:");
+        assemble_console_lines(alarum(), errors, "Errors:");
+        alarum() << std::flush;
         }
 }
 
diff --git a/tier_view_editor.cpp b/tier_view_editor.cpp
index ac80cdb..9d30cae 100644
--- a/tier_view_editor.cpp
+++ b/tier_view_editor.cpp
@@ -66,7 +66,7 @@ void tier_entity_adapter::set_bands_count(unsigned int n)
 
     if(n == 0)
         {
-        fatal_error() << "There must be at least one band." << LMI_FLUSH;
+        alarum() << "There must be at least one band." << LMI_FLUSH;
         }
 
     if(n == limits().size())
@@ -98,10 +98,7 @@ void tier_entity_adapter::set_bands_count(unsigned int n)
 
     if(limits().size() != values().size())
         {
-        fatal_error()
-            << "Inconsistent vector lengths."
-            << LMI_FLUSH
-            ;
+        alarum() << "Inconsistent vector lengths." << LMI_FLUSH;
         }
 }
 
@@ -133,10 +130,7 @@ void TierTableAdapter::EnsureIndexIsZero(unsigned int n) 
const
 {
     if(n != 0)
         {
-        fatal_error()
-            << "TierTableAdapter must have only one axis."
-            << LMI_FLUSH
-            ;
+        alarum() << "TierTableAdapter must have only one axis." << LMI_FLUSH;
         }
 }
 
@@ -152,10 +146,7 @@ bool TierTableAdapter::DoApplyAxisAdjustment
     TierBandAxis& ba = static_cast<TierBandAxis&>(axis);
     if(ba.GetMinValue() != 0 || ba.GetMaxValue() < ba.GetMinValue())
         {
-        fatal_error()
-            << "Band-axis adjuster has invalid limits."
-            << LMI_FLUSH
-            ;
+        alarum() << "Band-axis adjuster has invalid limits." << LMI_FLUSH;
         }
     unsigned int max_bound = GetBandsCount();
     updated = max_bound != (ba.GetMaxValue() + 1);
@@ -237,10 +228,7 @@ TierEditorGrid::enum_tier_grid_column 
TierEditorGrid::EnsureValidColumn
 {
     if(col != e_column_limit && col != e_column_value)
         {
-        fatal_error()
-            << "Grid has only two columns: Limit and Value."
-            << LMI_FLUSH
-            ;
+        alarum() << "Grid has only two columns: Limit and Value." << LMI_FLUSH;
         }
     return static_cast<enum_tier_grid_column>(col);
 }
diff --git a/tier_view_editor.hpp b/tier_view_editor.hpp
index 3af3b15..5cdcf14 100644
--- a/tier_view_editor.hpp
+++ b/tier_view_editor.hpp
@@ -119,7 +119,7 @@ inline tier_entity_adapter::tier_entity_adapter
 {
     if(limits.size() != values.size())
         {
-        fatal_error() << "Inconsistent vector lengths." << LMI_FLUSH;
+        alarum() << "Inconsistent vector lengths." << LMI_FLUSH;
         }
 }
 
@@ -180,7 +180,7 @@ struct FakeConversion
 // TODO ?? EVGENIY !! Is an actual implementation needed?
     void fail() const
     {
-        fatal_error() << "Dummy implementation called." << LMI_FLUSH;
+        alarum() << "Dummy implementation called." << LMI_FLUSH;
     }
   public:
     tier_entity_adapter::double_pair StringToValue(std::string const&) const
diff --git a/tn_range.tpp b/tn_range.tpp
index 2636b68..6a0468d 100644
--- a/tn_range.tpp
+++ b/tn_range.tpp
@@ -310,7 +310,7 @@ void trammel_base<T>::assert_sanity() const
 {
     if(!(nominal_minimum() <= nominal_maximum()))
         {
-        fatal_error()
+        alarum()
             << "Lower bound "
             << nominal_minimum()
             << " exceeds upper bound "
@@ -321,7 +321,7 @@ void trammel_base<T>::assert_sanity() const
         }
     if(!(nominal_minimum() <= default_value()))
         {
-        fatal_error()
+        alarum()
             << "Lower bound "
             << nominal_minimum()
             << " exceeds default value "
@@ -332,7 +332,7 @@ void trammel_base<T>::assert_sanity() const
         }
     if(!(default_value() <= nominal_maximum()))
         {
-        fatal_error()
+        alarum()
             << "Default value "
             << default_value()
             << " exceeds upper bound "
@@ -427,7 +427,7 @@ void tn_range<Number,Trammel>::minimum(Number n)
     Number candidate(adjust_minimum(n));
     if(!(trammel_.minimum_minimorum() <= candidate))
         {
-        fatal_error()
+        alarum()
             << "Cannot change lower bound to "
             << candidate
             << ", which is less than infimum "
@@ -438,7 +438,7 @@ void tn_range<Number,Trammel>::minimum(Number n)
         }
     if(!(candidate <= maximum()))
         {
-        fatal_error()
+        alarum()
             << "Cannot change lower bound to "
             << candidate
             << ", which is greater than upper bound "
@@ -471,7 +471,7 @@ void tn_range<Number,Trammel>::maximum(Number n)
     Number candidate(adjust_maximum(n));
     if(!(minimum() <= candidate))
         {
-        fatal_error()
+        alarum()
             << "Cannot change upper bound to "
             << candidate
             << ", which is less than lower bound "
@@ -482,7 +482,7 @@ void tn_range<Number,Trammel>::maximum(Number n)
         }
     if(!(candidate <= trammel_.maximum_maximorum()))
         {
-        fatal_error()
+        alarum()
             << "Cannot change upper bound to "
             << candidate
             << ", which is greater than supremum "
@@ -630,7 +630,7 @@ std::string 
tn_range<Number,Trammel>::format_limits_for_error_message() const
         }
     else
         {
-        fatal_error() << "Unanticipated case." << LMI_FLUSH;
+        alarum() << "Unanticipated case." << LMI_FLUSH;
         }
     return oss.str();
 }
@@ -708,7 +708,7 @@ std::string tn_range<Number,Trammel>::diagnose_invalidity
         }
     else
         {
-        fatal_error() << "Unanticipated case." << LMI_FLUSH;
+        alarum() << "Unanticipated case." << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/transferor.cpp b/transferor.cpp
index ded43e2..9918b24 100644
--- a/transferor.cpp
+++ b/transferor.cpp
@@ -131,7 +131,7 @@ bool Transferor::PerformTransfer(transfer_direction td)
 {
     if(!m_validatorWindow)
         {
-        fatal_error()
+        alarum()
             << "Validator for '"
             << name()
             << "' not bound to any control."
@@ -202,7 +202,7 @@ bool Transferor::PerformTransfer(transfer_direction td)
         return Transfer(td, data_,             *sequence    );
     else
         {
-        fatal_error()
+        alarum()
             << "Unrecognized control '"
             << name()
             << "'."
@@ -322,7 +322,7 @@ namespace
     {
         if(!(wxLB_SINGLE & control.GetWindowStyle()))
             {
-            fatal_error()
+            alarum()
                 << "CheckListBox '" << control.GetName() << "':"
                 << " must be constrained to a single selection."
                 << LMI_FLUSH
@@ -340,7 +340,7 @@ namespace
     {
         if(!(wxCB_READONLY & control.GetWindowStyle()))
             {
-            fatal_error()
+            alarum()
                 << "ComboBox '" << control.GetName() << "':"
                 << " must be read only."
                 << LMI_FLUSH
@@ -402,7 +402,7 @@ namespace
     {
         if(!(wxLB_SINGLE & control.GetWindowStyle()))
             {
-            fatal_error()
+            alarum()
                 << "ListBox '" << control.GetName() << "':"
                 << " must be constrained to a single selection."
                 << LMI_FLUSH
diff --git a/view_ex.tpp b/view_ex.tpp
index aaf6c92..81fdaa0 100644
--- a/view_ex.tpp
+++ b/view_ex.tpp
@@ -74,11 +74,7 @@ ViewType& PredominantView(wxDocument const& document)
         }
     if(!view)
         {
-        fatal_error()
-            << ViewName<ViewType>()
-            << ": view not found."
-            << LMI_FLUSH
-            ;
+        alarum() << ViewName<ViewType>() << ": view not found." << LMI_FLUSH;
         }
     return *view;
 }
@@ -97,11 +93,7 @@ ViewWindowType& PredominantViewWindow
     ViewWindowType* view_window_pointer = view.*view_window_member;
     if(!view_window_pointer)
         {
-        fatal_error()
-            << ViewName<ViewType>()
-            << ": window not found."
-            << LMI_FLUSH
-            ;
+        alarum() << ViewName<ViewType>() << ": window not found." << LMI_FLUSH;
         }
     return *view_window_pointer;
 }
diff --git a/wx_utility.cpp b/wx_utility.cpp
index 54edb78..b70e2d8 100644
--- a/wx_utility.cpp
+++ b/wx_utility.cpp
@@ -53,7 +53,7 @@ std::string ClipboardEx::GetText()
     wxClipboardLocker lock;
     if(!lock)
         {
-        fatal_error() << "Unable to lock clipboard." << LMI_FLUSH;
+        alarum() << "Unable to lock clipboard." << LMI_FLUSH;
         }
 
     wxTextDataObject z;
@@ -81,7 +81,7 @@ void ClipboardEx::SetText(std::string const& s)
     wxClipboardLocker lock;
     if(!lock)
         {
-        fatal_error() << "Unable to lock clipboard." << LMI_FLUSH;
+        alarum() << "Unable to lock clipboard." << LMI_FLUSH;
         }
 
     wxTextDataObject* TextDataObject = new(wx) wxTextDataObject(s);
@@ -178,7 +178,7 @@ void TestDateConversions()
                 );
         if(lmi_date1 != lmi_date0)
             {
-            fatal_error()
+            alarum()
                 << "Date conversion failed:\n"
                 << lmi_date0.str() << " original\n"
                 << lmi_date1.str() << " converted\n"
@@ -194,7 +194,7 @@ void TestDateConversions()
             );
         if(lmi_str != wx_str)
             {
-            fatal_error()
+            alarum()
                 << "ISO8601 representations differ:\n"
                 << lmi_str << " lmi\n"
                 << wx_str  << " wx\n"
@@ -305,7 +305,7 @@ std::string ValidateAndConvertFilename(wxString const& w)
 {
     if(w.IsEmpty())
         {
-        fatal_error() << "Filename is empty." << LMI_FLUSH;
+        alarum() << "Filename is empty." << LMI_FLUSH;
         }
     std::string s(w.mb_str());
     if(s.empty())
diff --git a/xml_lmi.cpp b/xml_lmi.cpp
index 098d6cf..31193c6 100644
--- a/xml_lmi.cpp
+++ b/xml_lmi.cpp
@@ -45,8 +45,8 @@ namespace xml_lmi
 ///
 /// Postconditions: member parser_ is valid.
 ///
-/// Throws: std::runtime_error, via fatal_error(), if a precondition
-/// is violated, or if xml-library calls throw an exception derived
+/// Throws: std::runtime_error, via alarum(), if a precondition is
+/// violated, or if xml-library calls throw an exception derived
 /// from std::exception.
 
 xml_lmi::dom_parser::dom_parser(std::string const& filename)
@@ -66,7 +66,7 @@ xml_lmi::dom_parser::dom_parser(std::string const& filename)
         }
     catch(std::exception const& e)
         {
-        fatal_error() << error_context_ << e.what() << LMI_FLUSH;
+        alarum() << error_context_ << e.what() << LMI_FLUSH;
         }
 }
 
@@ -76,8 +76,8 @@ xml_lmi::dom_parser::dom_parser(std::string const& filename)
 ///
 /// Postconditions: member parser_ is valid.
 ///
-/// Throws: std::runtime_error, via fatal_error(), if a precondition
-/// is violated, or if xml-library calls throw an exception derived
+/// Throws: std::runtime_error, via alarum(), if a precondition is
+/// violated, or if xml-library calls throw an exception derived
 /// from std::exception.
 
 xml_lmi::dom_parser::dom_parser(char const* data, std::size_t length)
@@ -89,7 +89,7 @@ xml_lmi::dom_parser::dom_parser(char const* data, std::size_t 
length)
         }
     catch(std::exception const& e)
         {
-        fatal_error() << error_context_ << e.what() << LMI_FLUSH;
+        alarum() << error_context_ << e.what() << LMI_FLUSH;
         }
 }
 
@@ -105,8 +105,8 @@ xml_lmi::dom_parser::dom_parser(char const* data, 
std::size_t length)
 ///
 /// Postconditions: member parser_ is valid.
 ///
-/// Throws: std::runtime_error, via fatal_error(), if a precondition
-/// is violated, or if xml-library calls throw an exception derived
+/// Throws: std::runtime_error, via alarum(), if a precondition is
+/// violated, or if xml-library calls throw an exception derived
 /// from std::exception.
 
 xml_lmi::dom_parser::dom_parser(std::istream const& is)
@@ -124,7 +124,7 @@ xml_lmi::dom_parser::dom_parser(std::istream const& is)
         }
     catch(std::exception const& e)
         {
-        fatal_error() << error_context_ << e.what() << LMI_FLUSH;
+        alarum() << error_context_ << e.what() << LMI_FLUSH;
         }
 }
 
@@ -136,8 +136,8 @@ xml_lmi::dom_parser::~dom_parser() = default;
 ///
 /// Preconditions: member parser_ has a document.
 ///
-/// Throws: std::runtime_error, via fatal_error(), if a precondition
-/// is violated, or if xml-library calls throw an exception derived
+/// Throws: std::runtime_error, via alarum(), if a precondition is
+/// violated, or if xml-library calls throw an exception derived
 /// from std::exception. Ctor postconditions are assumed to have been
 /// satisfied and are not tested.
 
@@ -149,7 +149,7 @@ xml_lmi::Document const& xml_lmi::dom_parser::document() 
const
         }
     catch(std::exception const& e)
         {
-        fatal_error() << error_context_ << e.what() << LMI_FLUSH;
+        alarum() << error_context_ << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -160,8 +160,8 @@ xml_lmi::Document const& xml_lmi::dom_parser::document() 
const
 /// has a root node; the argument, if not empty, matches the name of
 /// that root node.
 ///
-/// Throws: std::runtime_error, via fatal_error(), if a precondition
-/// is violated, or if xml-library calls throw an exception derived
+/// Throws: std::runtime_error, via alarum(), if a precondition is
+/// violated, or if xml-library calls throw an exception derived
 /// from std::exception. Ctor postconditions are assumed to have been
 /// satisfied and are not tested.
 
@@ -190,7 +190,7 @@ xml::element const& xml_lmi::dom_parser::root_node
         }
     catch(std::exception const& e)
         {
-        fatal_error() << error_context_ << e.what() << LMI_FLUSH;
+        alarum() << error_context_ << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -212,12 +212,7 @@ void xml_lmi::xml_document::save(std::string const& 
filename)
     bool okay = document_->save_to_file(filename.c_str());
     if(!okay)
         {
-        fatal_error()
-            << "Unable to save file '"
-            << filename
-            << "'."
-            << LMI_FLUSH
-            ;
+        alarum() << "Unable to save file '" << filename << "'." << LMI_FLUSH;
         }
 }
 
@@ -243,7 +238,7 @@ void xml_lmi::xml_document::add_comment(std::string const& 
s)
             return;
             }
         }
-    fatal_error() << "Cannot add comment to rootless document." << LMI_FLUSH;
+    alarum() << "Cannot add comment to rootless document." << LMI_FLUSH;
 }
 
 /// Find an element subnode by name, throwing if it is not found.
@@ -256,12 +251,7 @@ xml::node::const_iterator retrieve_element
     xml::node::const_iterator i = parent.find(name.c_str());
     if(parent.end() == i)
         {
-        fatal_error()
-            << "Required element '"
-            << name
-            << "' not found."
-            << LMI_FLUSH
-            ;
+        alarum() << "Required element '" << name << "' not found." << 
LMI_FLUSH;
         }
     return i;
 }
@@ -293,7 +283,7 @@ std::string get_content(xml::element const& element)
         }
     catch(std::exception const& e)
         {
-        fatal_error() << e.what() << LMI_FLUSH;
+        alarum() << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -309,7 +299,7 @@ std::string get_name(xml::element const& element)
         }
     catch(std::exception const& e)
         {
-        fatal_error() << e.what() << LMI_FLUSH;
+        alarum() << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -341,7 +331,7 @@ bool get_attr
         }
     catch(std::exception const& e)
         {
-        fatal_error() << e.what() << LMI_FLUSH;
+        alarum() << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
@@ -383,7 +373,7 @@ void set_attr
         }
     catch(std::exception const& e)
         {
-        fatal_error() << e.what() << LMI_FLUSH;
+        alarum() << e.what() << LMI_FLUSH;
         throw "Unreachable--silences a compiler diagnostic.";
         }
 }
diff --git a/xml_serializable.tpp b/xml_serializable.tpp
index 3b50a9a..5f65b13 100644
--- a/xml_serializable.tpp
+++ b/xml_serializable.tpp
@@ -52,7 +52,7 @@ void xml_serializable<T>::load(fs::path const& path)
 {
     if(access(path.string().c_str(), R_OK))
         {
-        fatal_error()
+        alarum()
             << "File '"
             << path.string()
             << "' is required but could not be found. Try reinstalling."
@@ -79,7 +79,7 @@ void xml_serializable<T>::read(xml::element const& x)
 {
     if(xml_root_name() != x.get_name())
         {
-        fatal_error()
+        alarum()
             << "XML node name is '"
             << x.get_name()
             << "' but '"
@@ -215,7 +215,7 @@ inline Y sfinae_cast
     ,typename std::enable_if<!std::is_same<X,Y>::value>::type* = nullptr
     )
 {
-    fatal_error() << "Impermissible type conversion." << LMI_FLUSH;
+    alarum() << "Impermissible type conversion." << LMI_FLUSH;
     return Y();
 }
 
@@ -306,7 +306,7 @@ void xml_serializable<T>::write_proem
 template<typename T>
 void xml_serializable<T>::handle_missing_version_attribute() const
 {
-    fatal_error()
+    alarum()
         << "XML tag <"
         << xml_root_name()
         << "> lacks required version attribute."
@@ -362,7 +362,7 @@ void xml_serializable<T>::redintegrate_ex_ante
         return;
         }
 
-    fatal_error()
+    alarum()
         << "Incompatible file version."
         << " An explicit override is necessary."
         << LMI_FLUSH
@@ -410,7 +410,7 @@ void xml_serializable<T>::redintegrate_ex_post
         return;
         }
 
-    fatal_error()
+    alarum()
         << "Incompatible file version."
         << " An explicit override is necessary."
         << LMI_FLUSH



reply via email to

[Prev in Thread] Current Thread [Next in Thread]