summaryrefslogtreecommitdiff
path: root/contrib/utility/Example/ExH/HelloWorld/hello_world.cpp
blob: ee678ffa66f0c05c0f546ae18de06d1e6713fb0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// file      : Example/ExH/HelloWorld/hello_world.cpp
// author    : Boris Kolpackov <boris@kolpackov.net>
// copyright : Copyright (c) 2002-2003 Boris Kolpackov
// license   : http://kolpackov.net/license.html

#include <cstdlib> // for std::abort ()

#include <string>
#include <iostream>

#include "Utility/ExH/System/Exception.hpp"
#include "Utility/ExH/Logic/Exception.hpp"

using std::cerr;
using std::cout;
using std::endl;

using namespace Utility;

class Application
{
public:
  class Exception : public ExH::Logic::Exception {};

  // Hint: you may want to try again...
  class FeelingDizzy  : public Exception {};

  class InvalidArg : public Exception {};

public:
  Application () throw (ExH::System::Exception)
      : // The std::string c-tor may throw any kind of exceptions besides
        // quite possible std::bad_alloc.
        greeting_ ("Hello, world!")
  {
  }

  Application (char const * greeting) throw (InvalidArg,
                                             ExH::System::Exception)
      : greeting_ (greeting == 0 ? "" : greeting)
  {
    if (greeting == 0) throw InvalidArg ();
  }

public:

  void
  run () throw (FeelingDizzy, ExH::System::Exception)
  {
    static unsigned int dizzy_count (0);

    if (dizzy_count++ < 5) throw FeelingDizzy ();

    // The next line can throw full bucket of exceptions
    // not to mention ios_base::failure.
    cout << greeting_.c_str () << endl;
  }

private:

  std::string  greeting_;
};



int
main ()
{
  // This is a catch-all layer that should be in use only
  // if we are really in trouble.
  try
  {
    // This is a catch-system layer. Here we will catch exceptions like
    // bad_alloc, etc. If we get here it means that nobody wanted/managed
    // to recover from this kind of errors.
    try
    {
      // This is a catch-logic layer. If we get here it usually
      // indicates an application logic error.
      try
      {

        // Ok, here we go about our application logic.
        try
        {
          for (int i = 0; i < 10; i++)
          {
            try
            {
              Application app ("Hi dude!");
              app.run ();
              break;
            }
            catch (Application::FeelingDizzy const& )
            {
              if (i == 9)
              {
                cerr << "Given up!" << endl;
                return -1;
              }
              else
              {
                cerr << "Application is feeling dizzy. Trying again..."
                     << endl;
              }
            }
          }
        }
        catch (Application::InvalidArg const& )
        {
          cerr << "Cought Application::InvalidArg : ...hmm... strange!"
               << endl;
          return -1;
        }
      }
      catch (ExH::Logic::Exception const& e)
      {
        cerr << "Caught Logic::Exception : " << e.what () << endl;
        return -1;
      }
    }
    catch (const ExH::System::Exception& e)
    {
      cerr << "Caught System::Exception : " << e.what () << endl;
      return -1;
    }
    catch (...)
    {
      cerr << "Caught unknown exception using catch-all handler. " << endl;
      return -1;
    }
  }
  catch (...)
  {
    // We get here in cases of some hard failure. For example when handling
    // exception, operator << throws another exception. Usually application
    // cannot handle such failures itself so we just propagate it futher.
    std::abort ();
  }
}
//$Id$