SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
uncaught_handler.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2008,2009,2010,2011,2012 Stephan Ossowski, Korbinian Schneeberger,
4  * Felix Ott, Joerg Hagmann, Alf Scotland, Sebastian Bender
5  *
6  * This file is part of SHORE.
7  *
8  * SHORE is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * SHORE is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with SHORE. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
25 
26 
27 #ifndef SHORE_PROGRAM_UNCAUGHT_HANDLER_HPP__
28 #define SHORE_PROGRAM_UNCAUGHT_HANDLER_HPP__
29 
30 #include <cerrno>
31 #include <cstring>
32 #include <iostream>
33 #include <stdexcept>
34 #include <string>
35 
36 #include <boost/filesystem.hpp>
37 #include <boost/version.hpp>
38 
40 #include "shore/stream/streams.hpp"
41 
42 namespace shore {
43 
46 {
47  public:
48 
49  enum Status
50  {
51  STATUS_OK,
52  STATUS_ERR_USAGE,
53  STATUS_ERR_FILESYSTEM,
54  STATUS_ERR_IO,
55  STATUS_ERR_RUNTIME,
56  STATUS_ERR_DOMAIN,
57  STATUS_ERR_LOGIC,
58  STATUS_ERR_EXCEPTION,
59  STATUS_ERR_ANY
60  };
61 
62  private:
63 
64  std::string m_name;
65  ostreams *m_os;
66  Status m_status;
67 
68  bool m_rethrow_exceptions;
69 
70  public:
71 
72  uncaught_handler(const std::string &name);
73 
75 
76  void set_rethrow_exceptions(const bool b);
77 
80  void set_stream(std::ostream &os);
81 
84  void set_file(const std::string &fn);
85 
87  void add_stream(std::ostream &os);
88 
90  void add_file(const std::string &fn);
91 
93  Status status() const;
94 
95  template<typename Func>
96  Status operator()(Func func)
97  {
98  m_status=STATUS_OK;
99 
100  #ifndef NOCATCH
101  try
102  #endif // NOCATCH
103  {
104  func();
105  }
106  #ifndef NOCATCH
107  catch(const av_parser::usage_error &e)
108  {
109  m_status=STATUS_ERR_USAGE;
110 
111  // re-throw: Usage exceptions are handled separately
112  // by shore::program
113  throw;
114  }
115  // basic_filesystem_error is the same as filesystem_error since boost 1.35
116  #if (BOOST_VERSION / 100) < 1035
117  catch(const boost::filesystem::basic_filesystem_error<boost::filesystem::path> &e)
118  {
119  m_status=STATUS_ERR_FILESYSTEM;
120 
121  (*m_os)<<m_name<<": filesystem error --- "<<e.what()
122  <<std::endl;
123 
124  (*m_os)<<"error code "<<e.system_error()
125  <<": "<<std::strerror(e.system_error());
126 
127  if(!e.path1().empty())
128  {
129  (*m_os)<<" {\""<<e.path1();
130  if(!e.path2().empty())
131  {
132  (*m_os)<<"\", \""<<e.path2();
133  }
134  (*m_os)<<"\"}";
135  }
136 
137  (*m_os)<<std::endl;
138 
139  if(m_rethrow_exceptions)
140  throw;
141  }
142  #endif // BOOST_VERSION
143  catch(const boost::filesystem::filesystem_error& e)
144  {
145  m_status=STATUS_ERR_FILESYSTEM;
146 
147  (*m_os)<<m_name<<": filesystem error --- "<<e.what()
148  <<std::endl;
149 
150  #if (BOOST_VERSION / 100) < 1035
151 
152  (*m_os)<<"error code "<<e.system_error()
153  <<": "<<std::strerror(e.system_error())<<std::endl;
154 
155  #else // BOOST_VERSION
156 
157  // boost >= v1.35
158  (*m_os)<<"error code "<<e.code().value()<<": "
159  <<e.code().message()<<std::endl;
160 
161  #endif // BOOST_VERSION
162 
163  if(m_rethrow_exceptions)
164  throw;
165  }
166  catch(const std::ios_base::failure& e)
167  {
168  m_status=STATUS_ERR_IO;
169 
170  (*m_os)<<m_name<<": read/write failure --- "<<e.what()
171  <<std::endl;
172 
173  if(m_rethrow_exceptions)
174  throw;
175  }
176  catch(const std::runtime_error& e)
177  {
178  m_status=STATUS_ERR_RUNTIME;
179 
180  (*m_os)<<m_name<<": runtime error --- "<<e.what()
181  <<std::endl;
182 
183  if(m_rethrow_exceptions)
184  throw;
185  }
186  catch(const std::domain_error& e)
187  {
188  m_status=STATUS_ERR_DOMAIN;
189 
190  (*m_os)<<m_name<<": domain error --- "<<e.what()
191  <<std::endl;
192 
193  if(m_rethrow_exceptions)
194  throw;
195  }
196  catch(const std::logic_error& e)
197  {
198  m_status=STATUS_ERR_LOGIC;
199 
200  (*m_os)<<m_name<<": logic error --- "<<e.what()
201  <<std::endl;
202  (*m_os)<<"Please report this bug."<<std::endl;
203 
204  if(m_rethrow_exceptions)
205  throw;
206  }
207  catch(const std::exception& e)
208  {
209  m_status=STATUS_ERR_EXCEPTION;
210 
211  (*m_os)<<m_name<<": exception --- "<<e.what()<<std::endl;
212 
213  if(m_rethrow_exceptions)
214  throw;
215  }
216  catch(...)
217  {
218  m_status=STATUS_ERR_ANY;
219 
220  (*m_os)<<m_name<<": error"<<std::endl;
221 
222  if(m_rethrow_exceptions)
223  throw;
224  }
225  #endif // NOCATCH
226 
227  return m_status;
228  }
229 };
230 
231 } // namespace shore
232 
233 #endif // SHORE_PROGRAM_UNCAUGHT_HANDLER_HPP__
234