sbuild-error.h

00001 /* Copyright © 2005-2007  Roger Leigh <rleigh@debian.org>
00002  *
00003  * schroot is free software: you can redistribute it and/or modify it
00004  * under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  *
00008  * schroot is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>.
00016  *
00017  *********************************************************************/
00018 
00019 #ifndef SBUILD_ERROR_H
00020 #define SBUILD_ERROR_H
00021 
00022 #include <map>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 
00027 #include <boost/format.hpp>
00028 #include <boost/type_traits.hpp>
00029 
00030 namespace sbuild
00031 {
00032 
00036   class error_base : public std::runtime_error
00037   {
00038   protected:
00044     error_base(std::string const& error):
00045       runtime_error(error),
00046       reason()
00047     {
00048     }
00049 
00056     error_base(std::string const& error,
00057           std::string const& reason):
00058       runtime_error(error),
00059       reason(reason)
00060     {
00061     }
00062 
00063   public:
00065     virtual ~error_base () throw ()
00066     {}
00067 
00073     virtual const char *
00074     why () const throw ()
00075     {
00076       return this->reason.c_str();
00077     }
00078 
00084     std::string const&
00085     get_reason () const
00086     {
00087       return this->reason;
00088     }
00089 
00095     void
00096     set_reason (std::string const& reason)
00097     {
00098       this->reason = reason;
00099     }
00100 
00101   private:
00103     std::string reason;
00104   };
00105 
00109   template <typename T>
00110   class error : public error_base
00111   {
00112   public:
00114     typedef T error_type;
00116     typedef std::map<error_type,const char *> map_type;
00117 
00123     error(std::string const& error):
00124       error_base(error)
00125     {
00126     }
00127 
00134     error(std::string const& error,
00135           std::string const& reason):
00136       error_base(error, reason)
00137     {
00138     }
00139 
00141     virtual ~error () throw ()
00142     {}
00143 
00144   private:
00146     static map_type error_strings;
00147 
00154     static const char *
00155     get_error (error_type error);
00156 
00157   protected:
00173     template <typename A, typename B, typename C,
00174               typename D, typename E, typename F>
00175     static std::string
00176     format_error (A const&   context1,
00177                   B const&   context2,
00178                   C const&   context3,
00179                   error_type error,
00180                   D const&   detail1,
00181                   E const&   detail2,
00182                   F const&   detail3);
00183 
00196     template <typename A, typename B, typename C,
00197               typename D, typename E, typename F>
00198     static std::string
00199     format_error (A const&                  context1,
00200                   B const&                  context2,
00201                   C const&                  context3,
00202                   std::runtime_error const& error,
00203                   D const&                  detail1,
00204                   E const&                  detail2,
00205                   F const&                  detail3);
00206 
00219     template <typename A, typename B, typename C,
00220               typename R, typename D, typename E, typename F>
00221     static std::string
00222     format_reason (A const&   context1,
00223                    B const&   context2,
00224                    C const&   context3,
00225                    R const&   error,
00226                    D const&   detail1,
00227                    E const&   detail2,
00228                    F const&   detail3);
00229 
00236     template<typename A>
00237     static void
00238     add_detail(boost::format& fmt,
00239                A const&       value);
00240 
00245     template<typename A, bool b>
00246     struct add_detail_helper
00247     {
00254       add_detail_helper(boost::format& fmt,
00255                         A const&       value)
00256       {
00257         fmt % value;
00258       }
00259     };
00260 
00265     template<typename A>
00266     struct add_detail_helper<A, true>
00267     {
00274       add_detail_helper(boost::format& fmt,
00275                         A const&       value)
00276       {
00277         fmt % value.what();
00278       }
00279     };
00280 
00287     template<typename A>
00288     static void
00289     add_reason(std::string& reason,
00290                A const&     value);
00291 
00296     template<typename A, bool b>
00297     struct add_reason_helper
00298     {
00305       add_reason_helper(std::string& reason,
00306                         A const&     value)
00307       {
00308       }
00309     };
00310 
00315     template<typename A>
00316     struct add_reason_helper<A, true>
00317     {
00324       add_reason_helper(std::string& reason,
00325                         A const&     value)
00326       {
00327         try
00328           {
00329             sbuild::error_base const& eb(dynamic_cast<sbuild::error_base const&>(value));
00330             if (!reason.empty())
00331               reason += '\n';
00332             reason += eb.why();
00333           }
00334         catch (std::bad_cast const& discard)
00335           {
00336           }
00337       }
00338     };
00339 
00340   };
00341 
00342 }
00343 
00344 #include "sbuild-error.tcc"
00345 
00346 #endif /* SBUILD_ERROR_H */
00347 
00348 /*
00349  * Local Variables:
00350  * mode:C++
00351  * End:
00352  */