TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/common/exceptions.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_COMMON_EXCEPTION_HPP_
00002 #define _TUTTLE_COMMON_EXCEPTION_HPP_
00003 
00004 namespace boost {
00005   struct errinfo_file_name_ {};
00006 }
00007 namespace tuttle { namespace exception {
00008     struct tag_userMessage {};
00009     struct tag_devMessage {};
00010     struct tag_backtraceMessage {};
00011     struct tag_ofxContext {};
00012     struct tag_ofxApi {};
00013     struct tag_pluginIdentifier {};
00014     struct tag_pluginName {};
00015     struct tag_nodeName {};
00016     struct tag_time {};
00017 }}
00018 
00019 #include "utils/boost_error_info_sstream.hpp"
00020 #include "utils/backtrace.hpp"
00021 
00022 #include <tuttle/common/ofx/core.hpp>
00023 #include <tuttle/common/ofx/utilities.hpp>
00024 #include <boost/version.hpp>
00025 #include <boost/lexical_cast.hpp>
00026 #include <boost/exception/exception.hpp>
00027 #include <boost/exception/info.hpp>
00028 #include <boost/exception/errinfo_file_name.hpp>
00029 #include <boost/exception/diagnostic_information.hpp>
00030 #include <boost/exception/get_error_info.hpp>
00031 
00032 #include <tuttle/common/utils/color.hpp>
00033 
00034 #include <ofxCorePlugin.h>
00035 #include <ofxImageEffect.h>
00036 
00037 #include <sstream>
00038 #include <string>
00039 #include <stdexcept>
00040 
00041 #define TUTTLE_LOG_EXCEPTION( e )  \
00042     TUTTLE_LOG_ERROR( "Exception:" ); \
00043     TUTTLE_LOG_ERROR( TUTTLE_GET_INFOS_FILE ); \
00044     TUTTLE_LOG_ERROR( TUTTLE_GET_INFOS_FUNCTION ); \
00045     TUTTLE_LOG_ERROR( "\t" << ::boost::diagnostic_information( e ) )
00046 
00047 #define TUTTLE_LOG_CURRENT_EXCEPTION  \
00048     TUTTLE_LOG_ERROR( "Exception:" ); \
00049     TUTTLE_LOG_ERROR( TUTTLE_GET_INFOS_FILE ); \
00050     TUTTLE_LOG_ERROR( TUTTLE_GET_INFOS_FUNCTION ); \
00051     TUTTLE_LOG_ERROR( "\t" << ::boost::current_exception_diagnostic_information() )
00052 
00053 #ifndef SWIG
00054 namespace OFX {
00055 typedef ::boost::error_info<struct tag_ofxStatus, ::OfxStatus> ofxStatus;
00056 inline std::string to_string( const ofxStatus& e )
00057 {
00058         return ::tuttle::ofx::mapStatusToString( e.value() );
00059 }
00060 }
00061 #endif
00062 
00063 namespace tuttle {
00064 
00065 /**
00066  * @brief To add quotes around a string.
00067  * @example quotes("toto") -> "\"toto\""
00068  */
00069 inline std::string quotes( const std::string& s )
00070 {
00071         return "\"" + s + "\"";
00072 }
00073 
00074 namespace exception {
00075 
00076 #ifndef SWIG
00077 /**
00078  * @brief Like a stringstream but using "operator+" instead of "operator<<".
00079  * Use a stringstream internally.
00080  */
00081 
00082 /**
00083  * @brief Standard tags you can use to add informations to your exceptions.
00084  *
00085  * @remark We use lower camel case for tags,
00086  *      to keep a difference between tags and exceptions.
00087  */
00088 /// @{
00089 /**
00090  * @brief If you catch an error at the top level, you can print this information to the user.
00091  * @remark User information.
00092  */
00093 typedef ::boost::error_info<struct tag_userMessage, ::boost::error_info_sstream> user;
00094 
00095 /**
00096  * @brief This is detailed informations for developpers.
00097  * Not always a real human readable message :)
00098  * @remark Dev information.
00099  */
00100 //typedef ::boost::error_info<struct tag_message,std::string> dev;
00101 typedef ::boost::error_info<struct tag_devMessage, ::boost::error_info_sstream> dev;
00102 //typedef ::boost::error_info_sstream<struct tag_message> dev;
00103 
00104 /**
00105  * @brief When we convert a C++ exception into a Python exception,
00106  *        we put the C++ backtrace into the message.
00107  * 
00108  * @remark Dev information.
00109  */
00110 typedef ::boost::error_info<struct tag_backtraceMessage, ::boost::error_info_sstream> backtrace;
00111 
00112 /**
00113  * @brief The ofx error status code.
00114  * @remark Dev information.
00115  */
00116 typedef ::OFX::ofxStatus ofxStatus;
00117 
00118 /**
00119  * @brief The ofx context name.
00120  * Each plugin can be instanciated in differents contexts (depending on the declaration of supported contexts).
00121  * @remark Dev information.
00122  */
00123 typedef ::boost::error_info<struct tag_ofxContext, ::std::string> ofxContext;
00124 /**
00125  * @brief The ofx api string identification.
00126  * @remark Dev information.
00127  */
00128 typedef ::boost::error_info<struct tag_ofxApi, ::std::string> ofxApi;
00129 /**
00130  * @brief Plugin string identifier.
00131  * @remark Dev information.
00132  */
00133 typedef ::boost::error_info<struct tag_pluginIdentifier, ::std::string> pluginIdentifier;
00134 /**
00135  * @brief Plugin name.
00136  * @remark User information.
00137  */
00138 typedef ::boost::error_info<struct tag_pluginName, ::std::string> pluginName;
00139 /**
00140  * @brief Node name.
00141  * @remark User information.
00142  */
00143 typedef ::boost::error_info<struct tag_nodeName, ::std::string> nodeName;
00144 /**
00145  * @brief Time.
00146  * @remark Dev or user information.
00147  */
00148 typedef ::boost::error_info<struct tag_time, OfxTime> time;
00149 /**
00150  * @brief Problem with a file.
00151  * @remark User information.
00152  */
00153 typedef ::boost::errinfo_file_name filename;
00154 /// @}
00155 #endif
00156 
00157 /** @brief Common exception for all tuttle plugin exceptions */
00158 struct Common : virtual public ::std::exception
00159         , virtual public ::boost::exception
00160         , virtual public ::boost::backtrace
00161 {};
00162 
00163 /// @brief Ofx standard errors
00164 /// @{
00165 
00166 /**
00167  * @brief You have to specify the exception::ofxStatus(kOfxStatXXX) yourself.
00168  * When you call a base level function (C API) which returns an ofxStatus, you can use this exception and fill it with the returned value using ofxStatus tag.
00169  */
00170 struct OfxCustom : virtual public Common
00171 {
00172         OfxCustom( const OfxStatus status )
00173         {
00174                 *this << ofxStatus( status );
00175         }
00176 };
00177 
00178 /** @brief Status error code for a failed operation */
00179 struct Failed : virtual public Common
00180 {
00181         Failed()
00182         {
00183                 * this << ofxStatus( kOfxStatFailed );
00184         }
00185 
00186 };
00187 
00188 /**
00189  * @brief Status error code for a fatal error
00190  *
00191  * Only returned in the case where the plug-in or host cannot continue to function and needs to be restarted.
00192  */
00193 struct Fatal : virtual public Common
00194 {
00195         Fatal()
00196         {
00197                 * this << ofxStatus( kOfxStatErrFatal );
00198         }
00199 
00200 };
00201 
00202 /** @brief Status error code for an operation on or request for an unknown object */
00203 struct Unknown : virtual public Common
00204 {
00205         Unknown()
00206         {
00207                 * this << ofxStatus( kOfxStatErrUnknown );
00208         }
00209 
00210 };
00211 
00212 /**
00213  * @brief Status error code returned by plug-ins when they are missing host functionality, either an API or some optional functionality (eg: custom params).
00214  *
00215  * Plug-Ins returning this should post an appropriate error message stating what they are missing.
00216  */
00217 struct MissingHostFeature : virtual Common
00218 {
00219         MissingHostFeature()
00220         {
00221                 * this << ofxStatus( kOfxStatErrMissingHostFeature );
00222         }
00223         MissingHostFeature( const std::string& feature )
00224         {
00225                 * this << ofxStatus( kOfxStatErrMissingHostFeature );
00226                 * this << user() + "Missing feature: " + quotes(feature);
00227         }
00228 };
00229 
00230 /** @brief Status error code for an unsupported feature/operation */
00231 struct Unsupported : virtual public Common
00232 {
00233         Unsupported()
00234         {
00235                 * this << ofxStatus( kOfxStatErrUnsupported );
00236         }
00237 
00238 };
00239 
00240 /** @brief Status error code for an operation attempting to create something that exists */
00241 struct Exists : virtual public Common
00242 {
00243         Exists()
00244         {
00245                 * this << ofxStatus( kOfxStatErrExists );
00246         }
00247 
00248 };
00249 
00250 /** @brief Status error code for an incorrect format */
00251 struct Format : virtual public Common
00252 {
00253         Format()
00254         {
00255                 * this << ofxStatus( kOfxStatErrFormat );
00256         }
00257 
00258 };
00259 
00260 /** @brief Status error code indicating that something failed due to memory shortage */
00261 struct Memory : virtual public Common
00262 {
00263         Memory()
00264         {
00265                 * this << ofxStatus( kOfxStatErrMemory );
00266         }
00267 
00268 };
00269 
00270 /** @brief Status error code for an operation on a bad handle */
00271 struct BadHandle : virtual public Common
00272 {
00273         BadHandle()
00274         {
00275                 * this << ofxStatus( kOfxStatErrBadHandle );
00276         }
00277 
00278 };
00279 
00280 /** @brief Status error code indicating that a given index was invalid or unavailable */
00281 struct BadIndex : virtual public Common
00282 {
00283         BadIndex()
00284         {
00285                 * this << ofxStatus( kOfxStatErrBadIndex );
00286         }
00287 
00288 };
00289 
00290 /** @brief Status error code indicating that something failed due an illegal value */
00291 struct Value : virtual public Common
00292 {
00293         Value()
00294         {
00295                 * this << ofxStatus( kOfxStatErrValue );
00296         }
00297 
00298 };
00299 
00300 /// @brief imageEffect specific errors
00301 /// @{
00302 
00303 /** @brief Error code for incorrect image formats */
00304 struct ImageFormat : virtual public Common
00305 {
00306         ImageFormat()
00307         {
00308                 * this << ofxStatus( kOfxStatErrImageFormat );
00309         }
00310 
00311 };
00312 /// @}
00313 /// @}
00314 
00315 /// @brief Other exceptions
00316 /// @{
00317 
00318 /**
00319  * @brief The class serves as the base class for all exceptions thrown to report errors presumably detectable before the program executes, such as violations of logical preconditions (cf. std::logic_error).
00320  * @remark With this exception, you normally have a "user" tag message.
00321  */
00322 struct Logic : virtual public Failed {};
00323 
00324 /**
00325  * @brief Something that should never appends.
00326  *        These exceptions may be replaced by assertions,
00327  *        but we prefer to keep a runtime check even in release (for the moment).
00328  * @remark With this exception, you should have a "dev" tag message.
00329  */
00330 struct Bug : virtual public Fatal {};
00331 
00332 /** @brief Unknown error inside a conversion. */
00333 struct BadConversion : virtual public Failed {};
00334 
00335 /** @brief Error with a NULL image buffer.
00336  * * plugin: The host launch a process, but the input clips are not filled (eg. NULL buffer pointer).
00337  *           The error comes from host.
00338  * * host:   Error with memory cache or memory pool.
00339  */
00340 struct ImageNotReady : virtual public Value {};
00341 
00342 /**
00343  * @brief A non optional input clip in not connected.
00344  * * plugin: Normally the host should not launch the render in this case.
00345  *           The error comes from host.
00346  * * host: We can't launch the render in this case.
00347  */
00348 struct ImageNotConnected : virtual public Failed {};
00349 
00350 /**
00351  * @brief Input property don't satisfy descriptor requirements.
00352  * * plugin:  The error comes from host.
00353  * * host: We can't launch the render in this case.
00354  */
00355 struct InputMismatch : virtual public Format {};
00356 
00357 /**
00358  * @brief Input and output properties mismatch.
00359  * * plugin:  The error comes from host.
00360  * * host: We can't launch the render in this case.
00361  */
00362 struct InOutMismatch : virtual public Format {};
00363 
00364 /**
00365  * @brief Input(s) and enventually output properties mismatch.
00366  * * plugin:  The error comes from host.
00367  * * host: We can't launch the render in this case.
00368  */
00369 struct BitDepthMismatch : virtual public ImageFormat {};
00370 
00371 /**
00372  * @brief Image raw bytes not valid.
00373  * * plugin:  The error comes from host.
00374  * * host: We can't launch the render in this case.
00375  */
00376 struct WrongRowBytes : virtual public ImageFormat {};
00377 
00378 /** @brief Status error code indicating that something failed due an illegal data. */
00379 struct Data : virtual public Value {};
00380 
00381 /** @brief Something that could work, but is not implemeted. */
00382 struct NotImplemented : virtual public Unsupported {};
00383 
00384 /** @brief The parameter doesn't make sense. */
00385 struct WrongParameter : virtual public Value {};
00386 
00387 /**
00388  * @brief File manipulation error.
00389  * eg. read only, file doesn't exists, etc.
00390  */
00391 struct File : virtual public Failed
00392 {
00393         File()
00394         {}
00395         File( const std::string& path )
00396         {
00397                 *this << user("File error.");
00398                 *this << filename(path);
00399         }
00400 };
00401 
00402 /**
00403  * @brief File doesn't exist.
00404  */
00405 struct FileNotExist : virtual public File
00406 {
00407         FileNotExist()
00408         {}
00409         FileNotExist( const std::string& path )
00410         {
00411                 *this << user("No such file.");
00412                 *this << filename(path);
00413         }
00414 };
00415 
00416 /**
00417  * @brief File already exists.
00418  */
00419 struct FileExist : virtual public File
00420 {
00421         FileExist()
00422         {}
00423         FileExist( const std::string& path )
00424         {
00425                 *this << user("File already exists.");
00426                 *this << filename(path);
00427         }
00428 };
00429 
00430 /**
00431  * @brief File in sequence doesn't exist.
00432  */
00433 struct FileInSequenceNotExist : virtual public File
00434 {
00435         FileInSequenceNotExist()
00436         {}
00437         FileInSequenceNotExist( const std::string& path )
00438         {
00439                 *this << user("No such file.");
00440                 *this << filename(path);
00441         }
00442 };
00443 
00444 /**
00445  * @brief Directory doesn't exist.
00446  */
00447 struct NoDirectory : virtual public File
00448 {
00449         NoDirectory()
00450         {}
00451         NoDirectory( const std::string& path )
00452         {
00453                 *this << user("No such directory.");
00454                 *this << filename(path);
00455         }
00456 };
00457 
00458 /**
00459  * @brief Read only file.
00460  */
00461 struct ReadOnlyFile : virtual public File
00462 {
00463         ReadOnlyFile()
00464         {}
00465         ReadOnlyFile( const std::string& path )
00466         {
00467                 *this << user("Read-only file.");
00468                 *this << filename(path);
00469         }
00470 };
00471 /// @}
00472 
00473 std::string format_exception_message( const ::boost::exception& e );
00474 std::string format_exception_info( const ::boost::exception& e );
00475 std::string format_current_exception();
00476 
00477 }
00478 }
00479 
00480 #endif