sbuild  1.7.1
error.h
1 /* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org>
2  *
3  * schroot is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * schroot is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see
15  * <http://www.gnu.org/licenses/>.
16  *
17  *********************************************************************/
18 
19 #ifndef SBUILD_ERROR_H
20 #define SBUILD_ERROR_H
21 
22 #include <map>
23 #include <stdexcept>
24 #include <string>
25 #include <typeinfo>
26 
27 #include <boost/format.hpp>
28 #include <boost/type_traits.hpp>
29 
30 namespace sbuild
31 {
32 
36  class error_base : public std::runtime_error
37  {
38  protected:
44  error_base(const std::string& error):
45  runtime_error(error),
46  reason()
47  {
48  }
49 
56  error_base(const std::string& error,
57  const std::string& reason):
58  runtime_error(error),
59  reason(reason)
60  {
61  }
62 
63  public:
65  virtual ~error_base () throw ()
66  {}
67 
73  virtual const char *
74  why () const throw ()
75  {
76  return this->reason.c_str();
77  }
78 
84  std::string const&
85  get_reason () const
86  {
87  return this->reason;
88  }
89 
95  void
96  set_reason (const std::string& reason)
97  {
98  this->reason = reason;
99  }
100 
101  private:
103  std::string reason;
104  };
105 
109  template <typename T>
110  class error : public error_base
111  {
112  public:
114  typedef T error_type;
116  typedef std::map<error_type,const char *> map_type;
117 
123  error(const std::string& error):
124  error_base(error)
125  {
126  }
127 
134  error(const std::string& error,
135  const std::string& reason):
136  error_base(error, reason)
137  {
138  }
139 
141  virtual ~error () throw ()
142  {}
143 
144  private:
147 
154  static const char *
156 
157  protected:
173  template <typename A, typename B, typename C,
174  typename D, typename E, typename F>
175  static std::string
176  format_error (A const& context1,
177  B const& context2,
178  C const& context3,
180  D const& detail1,
181  E const& detail2,
182  F const& detail3);
183 
196  template <typename A, typename B, typename C,
197  typename D, typename E, typename F>
198  static std::string
199  format_error (A const& context1,
200  B const& context2,
201  C const& context3,
202  const std::runtime_error& error,
203  D const& detail1,
204  E const& detail2,
205  F const& detail3);
206 
219  template <typename A, typename B, typename C,
220  typename R, typename D, typename E, typename F>
221  static std::string
222  format_reason (A const& context1,
223  B const& context2,
224  C const& context3,
225  R const& error,
226  D const& detail1,
227  E const& detail2,
228  F const& detail3);
229 
237  static void
238  add_detail(boost::format& fmt,
239  const std::nullptr_t& value);
240 
247  template<typename A>
248  static void
249  add_detail(boost::format& fmt,
250  A const& value);
251 
256  template<typename A, bool b>
258  {
265  add_detail_helper(boost::format& fmt,
266  A const& value)
267  {
268  fmt % value;
269  }
270  };
271 
276  template<typename A>
277  struct add_detail_helper<A, true>
278  {
285  add_detail_helper(boost::format& fmt,
286  A const& value)
287  {
288  fmt % value.what();
289  }
290  };
291 
298  template<typename A>
299  static void
300  add_reason(std::string& reason,
301  A const& value);
302 
307  template<typename A, bool b>
309  {
316  add_reason_helper(std::string& reason,
317  A const& value)
318  {
319  }
320  };
321 
326  template<typename A>
327  struct add_reason_helper<A, true>
328  {
335  add_reason_helper(std::string& reason,
336  A const& value)
337  {
338  try
339  {
340  const sbuild::error_base& eb(dynamic_cast<sbuild::error_base const&>(value));
341  if (!reason.empty())
342  reason += '\n';
343  reason += eb.why();
344  }
345  catch (const std::bad_cast& discard)
346  {
347  }
348  }
349  };
350 
351  };
352 
353 }
354 
355 #include <sbuild/error.tcc>
356 
357 #endif /* SBUILD_ERROR_H */
358 
359 /*
360  * Local Variables:
361  * mode:C++
362  * End:
363  */