Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
exception-error-test.cpp
Go to the documentation of this file.
1 /*
2  ExceptionError(Test) - throwing and catching our exception type
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
29 #include "lib/error.h"
30 #include "lib/error.hpp"
31 #include "lib/test/run.hpp"
32 #include "lib/format-cout.hpp"
33 #include "lib/util.hpp"
34 
35 #include <exception>
36 #include <stdexcept>
37 #include <string>
38 
39 using std::runtime_error;
40 using std::exception;
41 using std::string;
42 
43 
44 
45 namespace lumiera {
46  namespace test {
47 
48  LUMIERA_ERROR_DEFINE (LIFE_AND_UNIVERSE, "and everything?");
52  LUMIERA_ERROR_DECLARE(DERIVED);
53  LUMIERA_ERROR_DEFINE (DERIVED, "convoluted exception");
54 
57 
58 
59  /******************************************************/
67  class ExceptionError_test : public Test
68  {
70  virtual void run (Arg arg)
71  {
72  if (0 < arg.size() and arg[1]=="terminate")
74 
75 
77  catcher (&test::throwDerived, "test-1");
78  catcher (&test::throwFatal, "test-2");
79  catcher (&test::throwInvalid, "test-3");
80  catcher (&test::throwExternal, "test-4");
81  catcher (&test::throwRuntime, "test-5");
82  catcher (&test::throwExceptn, "test-6");
83 
84  catcher (&test::nestedThrower, "test-7");
85  catcher (&test::doubleNestedTh,"test-8");
86 
90  }
91 
92 
93 
95  void throwSpecial (string ) { throw SpecificError(); }
96  void throwDerived (string ) { throw DerivedError(); }
97  void throwFatal (string _) { throw error::Fatal(_); }
98  void throwInvalid (string _) { throw error::Invalid(_); }
99  void throwExternal(string _) { throw error::External(_); }
100  void throwRuntime (string _) { throw std::runtime_error(_); }
101  void throwExceptn (string ) { throw std::exception(); }
102 
103 
113  void nestedThrower (string msg)
114  {
115  try { throwExternal(msg); }
116  catch (std::exception& e)
117  {
118  cout << "intermediate handler caught: " << e.what()
119  << "....will rethrow as error::State\n";
120  throw error::State (e);
121  }
122  }
123 
125  void doubleNestedTh (string msg)
126  {
127  try { nestedThrower (msg); }
128  catch (Error& e)
129  {
130  cout << "2nd intermediate handler caught: " << e.what()
131  << "....will rethrow as error::Config\n";
132  throw error::Config (e);
133  }
134  }
135 
136 
141  {
142  lumiera_error ();
143  CHECK (not lumiera_error());
144 
145  Error err1;
146  Error err2("boo",LERR_(DERIVED));
147  CHECK (err1.getID () == lumiera_error ()); // (we didn't clear the first one!)
148 
149  Error err3("boooo",LERR_(DERIVED));
150  CHECK (err3.getID () == lumiera_error ());
151 
152  SpecificError err4;
153  CHECK (err4.getID () == LERR_(LIFE_AND_UNIVERSE));
154  CHECK (err4.getID () == lumiera_error ());
155 
156  CHECK (not lumiera_error());
157  }
158 
159 
160  void detectErrorflag (string) { throwOnError(); }
161  void detectErrorflagChained (string msg) { maybeThrow<error::Logic> (msg); }
162 
163 
168  {
169  lumiera_error_set(LERR_(LIFE_AND_UNIVERSE), "what is the answer?");
170  CHECK (lumiera_error_peek());
171 
173  CHECK (LERR_(LIFE_AND_UNIVERSE) == lumiera_error_peek());
174 
175  catcher (&test::detectErrorflagChained, "the big bang");
176  CHECK (LERR_(LIFE_AND_UNIVERSE) == lumiera_error());
177  }
178 
179 
184  {
185  error::Logic err1;
186  error::Config err2(err1);
187  error::Config err3(err2);
188  Error err4(err1); // note: copy ctor
189 
190  std::runtime_error rerr("what a shame");
191  error::External err5(rerr);
192  Error err6(err5);
193 
194  CHECK (err2.rootCause() == err1.what());
195  CHECK (err3.rootCause() == err1.what());
196  CHECK (err4.rootCause() == err1.rootCause()); // mere copy is not a root cause
197 
198  CHECK (err5.rootCause() == rerr.what());
199  CHECK (err6.rootCause() == rerr.what());
200  }
201 
202 
209  void terminateUnknown () noexcept
210  {
211  throw Error("You'll never get me, won't you?");
212  }
213 
214 
220  : public error::Invalid
221  {
222  int value_;
223  public:
225  : error::Invalid{"don't panic", LUMIERA_ERROR_LIFE_AND_UNIVERSE}
226  , value_(42)
227  { }
228 
229  int
231  {
232  return value_;
233  }
234  };
235 
236 
237 
241  void catcher (void (ExceptionError_test::*funky)(string), string context)
242  {
243  try
244  {
245  (this->*funky) (context);
246  }
247 
248  catch (SpecificError& e) { cout << "caught: " << e.what() << "..the answer is: " << e.revealIt() << "\n"; }
249  catch (error::Logic& e) { cout << "caught error::Logic: " << e.what() << "\n"; }
250  catch (error::Invalid&e) { cout << "caught error::Invalid: " << e.what() << "\n"; }
251  catch (Error& e) { cout << "caught lumiera::Error: " << e.what() << "\n"; }
252  catch (runtime_error& e) { cout << "caught std::runtime_error: " << e.what() << "\n"; }
253  catch (exception& e) { cout << "caught std::exception. (unspecific)" << "\n"; }
254  catch (...) { cout << "caught an unknown exception\n"; }
255  }
256  };
257 
258 
259 
261  LAUNCHER (ExceptionError_test, "function common");
262 
263 
264  } // namespace test
265 
266 } // namespace util
267 
lumiera_err lumiera_error_peek(void)
Check current error state without clearing it Please avoid this function and use lumiera_error() if p...
Definition: error-state.c:142
Automatically use custom string conversion in C++ stream output.
LumieraError< LERR_(INVALID)> Invalid
Definition: error.hpp:216
lumiera_err getID() const noexcept
the internal Lumiera-error-ID (was set as C-errorstate in ctor)
Definition: error.hpp:101
LUMIERA_ERROR_DECLARE(DERIVED)
local specific error-constant for use in the constructor of the nested SpecificError class...
#define _(String)
Definition: gtk-base.hpp:76
Definition: run.hpp:49
void catcher(void(ExceptionError_test::*funky)(string), string context)
helper: provides a bunch of catch-clauses and runs the given member functions within ...
void throwOnError()
Check the lumiera error state, which maybe was set by C-code.
Definition: error.hpp:239
Some aspects of C++ exception handling.
Lumiera error handling (C interface).
Derived specific exceptions within Lumiera's exception hierarchy.
Definition: error.hpp:196
LAUNCHER(SubsystemRunner_test,"function common")
Register this test class...
error::LumieraError< LERR_(DERIVED), error::External > DerivedError
define a specific Error subclass derived from error::external
std::vector< string > & Arg
Definition: run.hpp:54
#define LERR_(_NAME_)
Definition: error.hpp:58
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
LumieraError< LERR_(STATE)> State
Definition: error.hpp:214
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:124
string const & rootCause() const noexcept
If this exception was caused by a chain of further exceptions, return the description of the first on...
Definition: error.hpp:120
LUMIERA_ERROR_DEFINE(LIFE_AND_UNIVERSE,"and everything?")
Lumiera error handling (C++ interface).
lumiera_err lumiera_error_set(lumiera_err nerr, const char *extra)
Set error state for the current thread.
Definition: error-state.c:105
LumieraError< LERR_(EXTERNAL)> External
Definition: error.hpp:218
virtual CStr what() const noexceptoverride
std::exception interface : yield a diagnostic message
Lumiera public interface.
a very specific Exception class local to this scope and with additional behaviour.
LumieraError< LERR_(CONFIG), Invalid > Config
Definition: error.hpp:217
Interface and Base definition for all Lumiera Exceptions.
Definition: error.hpp:69
LumieraError< LERR_(FATAL), Logic > Fatal
Definition: error.hpp:213