aboutsummaryrefslogtreecommitdiffstats
path: root/include/qpdf/QEXC.hh
blob: b94edf7a1e63e3eccb8299fbbaee10dd091b042d (plain) (blame)
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
// Copyright (c) 2005-2008 Jay Berkenbilt
//
// This file is part of qpdf.  This software may be distributed under
// the terms of version 2 of the Artistic License which may be found
// in the source distribution.  It is provided "as is" without express
// or implied warranty.

#ifndef __QEXC_HH__
#define __QEXC_HH__

#include <string>
#include <exception>
#include <errno.h>

namespace QEXC
{
    // This namespace contains all exception classes used by the
    // library.

    // The class hierarchy is as follows:

    //   std::exception
    //   |
    //   +-> QEXC::Base
    //       |
    //       +-> QEXC::General
    //       |
    //       +-> QEXC::Internal

    // QEXC::General is the base class of all standard user-defined
    // exceptions and "expected" error conditions raised by QClass.
    // Applications or libraries using QClass are encouraged to derive
    // their own exceptions from these classes if they wish.  It is
    // entirely reasonable for code to catch QEXC::General or specific
    // subclasses of it as part of normal error handling.

    // QEXC::Internal is reserved for internal errors.  These should
    // be used only for situations that indicate a likely bug in the
    // software itself.  This may include improper use of a library
    // function.  Operator errors should not be able to cause Internal
    // errors.  (There may be some exceptions to this such as users
    // invoking programs that were intended only to be invoked by
    // other programs.)  QEXC::Internal should generally not be
    // trapped except in terminate handlers or top-level exception
    // handlers which will want to translate them into error messages
    // and cause the program to exit.  Such top-level handlers may
    // want to catch std::exception instead.

    // All subclasses of QEXC::Base implement a const unparse() method
    // which returns a std::string const&.  They also override
    // std::exception::what() to return a char* with the same value.
    // unparse() should be implemented in such a way that a program
    // catching QEXC::Base or std::exception can use the text returned
    // by unparse() (or what()) without any exception-specific
    // adornment.  (The program may prefix the program name or other
    // general information.)  Note that std::exception::what() is a
    // const method that returns a const char*.  For this reason, it
    // is essential that unparse() return a const reference to a
    // string so that what() can be implemented by calling unparse().
    // This means that the string that unparse() returns a reference
    // to must not be allocated on the stack in the call to unparse().
    // The recommended way to do this is for derived exception classes
    // to store their string descriptions by calling the protected
    // setMessage() method and then to not override unparse().

    class Base: public std::exception
    {
	// This is the common base class for all exceptions in qclass.
	// Application/library code should not generally catch this
	// directly.  See above for caveats.
      public:
	Base();
	Base(std::string const& message);
	virtual ~Base() throw() {}
	virtual std::string const& unparse() const;
	virtual const char* what() const throw();

      protected:
	void setMessage(std::string const& message);

      private:
	std::string message;
    };

    class General: public Base
    {
	// This is the base class for normal user/library-defined
	// error conditions.
      public:
	General();
	General(std::string const& message);
	virtual ~General() throw() {};
    };

    // Note that Internal is not derived from General.  Internal
    // errors are too severe.  We don't want internal errors
    // accidentally trapped as part of QEXC::General.  If you are
    // going to deal with internal errors, you have to do so
    // explicitly.
    class Internal: public Base
    {
      public:
	Internal(std::string const& message);
	virtual ~Internal() throw() {};
    };

    class System: public General
    {
      public:
	System(std::string const& prefix, int sys_errno);
	virtual ~System() throw() {};
	int getErrno() const;

      private:
	int sys_errno;
    };
};

#endif // __QEXC_HH__