except.hxx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. /** Definition of libpqxx exception classes.
  2. *
  3. * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ...
  4. *
  5. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead.
  6. *
  7. * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
  8. *
  9. * See COPYING for copyright license. If you did not receive a file called
  10. * COPYING with this source code, please notify the distributor of this mistake,
  11. * or contact the author.
  12. */
  13. #ifndef PQXX_H_EXCEPT
  14. #define PQXX_H_EXCEPT
  15. #include "pqxx/compiler-public.hxx"
  16. #include "pqxx/compiler-internal-pre.hxx"
  17. #include <stdexcept>
  18. #include "pqxx/util.hxx"
  19. namespace pqxx
  20. {
  21. /**
  22. * @addtogroup exception Exception classes
  23. *
  24. * These exception classes follow, roughly, the two-level hierarchy defined by
  25. * the PostgreSQL error codes (see Appendix A of the PostgreSQL documentation
  26. * corresponding to your server version). The hierarchy given here is, as yet,
  27. * not a complete mirror of the error codes. There are some other differences
  28. * as well, e.g. the error code statement_completion_unknown has a separate
  29. * status in libpqxx as in_doubt_error, and too_many_connections is classified
  30. * as a broken_connection rather than a subtype of insufficient_resources.
  31. *
  32. * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html
  33. *
  34. * @{
  35. */
  36. /// Mixin base class to identify libpqxx-specific exception types
  37. /**
  38. * If you wish to catch all exception types specific to libpqxx for some reason,
  39. * catch this type. All of libpqxx's exception classes are derived from it
  40. * through multiple-inheritance (they also fit into the standard library's
  41. * exception hierarchy in more fitting places).
  42. *
  43. * This class is not derived from std::exception, since that could easily lead
  44. * to exception classes with multiple std::exception base-class objects. As
  45. * Bart Samwel points out, "catch" is subject to some nasty fineprint in such
  46. * cases.
  47. */
  48. class PQXX_LIBEXPORT PQXX_NOVTABLE pqxx_exception
  49. {
  50. public:
  51. /// Support run-time polymorphism, and keep this class abstract
  52. virtual ~pqxx_exception() noexcept =0;
  53. /// Return std::exception base-class object
  54. /** Use this to get at the exception's what() function, or to downcast to a
  55. * more specific type using dynamic_cast.
  56. *
  57. * Casting directly from pqxx_exception to a specific exception type is not
  58. * likely to work since pqxx_exception is not (and could not safely be)
  59. * derived from std::exception.
  60. *
  61. * For example, to test dynamically whether an exception is an sql_error:
  62. *
  63. * @code
  64. * try
  65. * {
  66. * // ...
  67. * }
  68. * catch (const pqxx::pqxx_exception &e)
  69. * {
  70. * std::cerr << e.base().what() << std::endl;
  71. * const pqxx::sql_error *s=dynamic_cast<const pqxx::sql_error*>(&e.base());
  72. * if (s) std::cerr << "Query was: " << s->query() << std::endl;
  73. * }
  74. * @endcode
  75. */
  76. PQXX_CONST virtual const std::exception &base() const noexcept =0; //[t00]
  77. };
  78. /// Run-time failure encountered by libpqxx, similar to std::runtime_error
  79. class PQXX_LIBEXPORT failure :
  80. public pqxx_exception, public std::runtime_error
  81. {
  82. virtual const std::exception &base() const noexcept override
  83. { return *this; }
  84. public:
  85. explicit failure(const std::string &);
  86. };
  87. /// Exception class for lost or failed backend connection.
  88. /**
  89. * @warning When this happens on Unix-like systems, you may also get a SIGPIPE
  90. * signal. That signal aborts the program by default, so if you wish to be able
  91. * to continue after a connection breaks, be sure to disarm this signal.
  92. *
  93. * If you're working on a Unix-like system, see the manual page for
  94. * @c signal (2) on how to deal with SIGPIPE. The easiest way to make this
  95. * signal harmless is to make your program ignore it:
  96. *
  97. * @code
  98. * #include <signal.h>
  99. *
  100. * int main()
  101. * {
  102. * signal(SIGPIPE, SIG_IGN);
  103. * // ...
  104. * @endcode
  105. */
  106. class PQXX_LIBEXPORT broken_connection : public failure
  107. {
  108. public:
  109. broken_connection();
  110. explicit broken_connection(const std::string &);
  111. };
  112. /// Exception class for failed queries.
  113. /** Carries, in addition to a regular error message, a copy of the failed query
  114. * and (if available) the SQLSTATE value accompanying the error.
  115. */
  116. class PQXX_LIBEXPORT sql_error : public failure
  117. {
  118. /// Query string. Empty if unknown.
  119. const std::string m_query;
  120. /// SQLSTATE string describing the error type, if known; or empty string.
  121. const std::string m_sqlstate;
  122. public:
  123. explicit sql_error(
  124. const std::string &msg="",
  125. const std::string &Q="",
  126. const char sqlstate[]=nullptr);
  127. virtual ~sql_error() noexcept;
  128. /// The query whose execution triggered the exception
  129. PQXX_PURE const std::string &query() const noexcept; //[t56]
  130. /// SQLSTATE error code if known, or empty string otherwise.
  131. PQXX_PURE const std::string &sqlstate() const noexcept;
  132. };
  133. /// "Help, I don't know whether transaction was committed successfully!"
  134. /** Exception that might be thrown in rare cases where the connection to the
  135. * database is lost while finishing a database transaction, and there's no way
  136. * of telling whether it was actually executed by the backend. In this case
  137. * the database is left in an indeterminate (but consistent) state, and only
  138. * manual inspection will tell which is the case.
  139. */
  140. class PQXX_LIBEXPORT in_doubt_error : public failure
  141. {
  142. public:
  143. explicit in_doubt_error(const std::string &);
  144. };
  145. /// The backend saw itself forced to roll back the ongoing transaction.
  146. class PQXX_LIBEXPORT transaction_rollback : public failure
  147. {
  148. public:
  149. explicit transaction_rollback(const std::string &);
  150. };
  151. /// Transaction failed to serialize. Please retry it.
  152. /** Can only happen at transaction isolation levels REPEATABLE READ and
  153. * SERIALIZABLE.
  154. *
  155. * The current transaction cannot be committed without violating the guarantees
  156. * made by its isolation level. This is the effect of a conflict with another
  157. * ongoing transaction. The transaction may still succeed if you try to
  158. * perform it again.
  159. */
  160. class PQXX_LIBEXPORT serialization_failure : public transaction_rollback
  161. {
  162. public:
  163. explicit serialization_failure(const std::string &);
  164. };
  165. /// We can't tell whether our last statement succeeded.
  166. class PQXX_LIBEXPORT statement_completion_unknown : public transaction_rollback
  167. {
  168. public:
  169. explicit statement_completion_unknown(const std::string &);
  170. };
  171. /// The ongoing transaction has deadlocked. Retrying it may help.
  172. class PQXX_LIBEXPORT deadlock_detected : public transaction_rollback
  173. {
  174. public:
  175. explicit deadlock_detected(const std::string &);
  176. };
  177. /// Internal error in libpqxx library
  178. class PQXX_LIBEXPORT internal_error :
  179. public pqxx_exception, public std::logic_error
  180. {
  181. virtual const std::exception &base() const noexcept override
  182. { return *this; }
  183. public:
  184. explicit internal_error(const std::string &);
  185. };
  186. /// Error in usage of libpqxx library, similar to std::logic_error
  187. class PQXX_LIBEXPORT usage_error :
  188. public pqxx_exception, public std::logic_error
  189. {
  190. virtual const std::exception &base() const noexcept override
  191. { return *this; }
  192. public:
  193. explicit usage_error(const std::string &);
  194. };
  195. /// Invalid argument passed to libpqxx, similar to std::invalid_argument
  196. class PQXX_LIBEXPORT argument_error :
  197. public pqxx_exception, public std::invalid_argument
  198. {
  199. virtual const std::exception &base() const noexcept override
  200. { return *this; }
  201. public:
  202. explicit argument_error(const std::string &);
  203. };
  204. /// Value conversion failed, e.g. when converting "Hello" to int.
  205. class PQXX_LIBEXPORT conversion_error :
  206. public pqxx_exception, public std::domain_error
  207. {
  208. virtual const std::exception &base() const noexcept override
  209. { return *this; }
  210. public:
  211. explicit conversion_error(const std::string &);
  212. };
  213. /// Something is out of range, similar to std::out_of_range
  214. class PQXX_LIBEXPORT range_error :
  215. public pqxx_exception, public std::out_of_range
  216. {
  217. virtual const std::exception &base() const noexcept override
  218. { return *this; }
  219. public:
  220. explicit range_error(const std::string &);
  221. };
  222. /// Query returned an unexpected number of rows.
  223. class PQXX_LIBEXPORT unexpected_rows : public range_error
  224. {
  225. virtual const std::exception &base() const noexcept override
  226. { return *this; }
  227. public:
  228. explicit unexpected_rows(const std::string &msg) : range_error{msg} {}
  229. };
  230. /// Database feature not supported in current setup
  231. class PQXX_LIBEXPORT feature_not_supported : public sql_error
  232. {
  233. public:
  234. explicit feature_not_supported(
  235. const std::string &err,
  236. const std::string &Q="",
  237. const char sqlstate[]=nullptr) :
  238. sql_error{err, Q, sqlstate} {}
  239. };
  240. /// Error in data provided to SQL statement
  241. class PQXX_LIBEXPORT data_exception : public sql_error
  242. {
  243. public:
  244. explicit data_exception(
  245. const std::string &err,
  246. const std::string &Q="",
  247. const char sqlstate[]=nullptr) :
  248. sql_error{err, Q, sqlstate} {}
  249. };
  250. class PQXX_LIBEXPORT integrity_constraint_violation : public sql_error
  251. {
  252. public:
  253. explicit integrity_constraint_violation(
  254. const std::string &err,
  255. const std::string &Q="",
  256. const char sqlstate[]=nullptr) :
  257. sql_error{err, Q, sqlstate} {}
  258. };
  259. class PQXX_LIBEXPORT restrict_violation :
  260. public integrity_constraint_violation
  261. {
  262. public:
  263. explicit restrict_violation(
  264. const std::string &err,
  265. const std::string &Q="",
  266. const char sqlstate[]=nullptr) :
  267. integrity_constraint_violation{err, Q, sqlstate} {}
  268. };
  269. class PQXX_LIBEXPORT not_null_violation :
  270. public integrity_constraint_violation
  271. {
  272. public:
  273. explicit not_null_violation(
  274. const std::string &err,
  275. const std::string &Q="",
  276. const char sqlstate[]=nullptr) :
  277. integrity_constraint_violation{err, Q, sqlstate} {}
  278. };
  279. class PQXX_LIBEXPORT foreign_key_violation :
  280. public integrity_constraint_violation
  281. {
  282. public:
  283. explicit foreign_key_violation(
  284. const std::string &err,
  285. const std::string &Q="",
  286. const char sqlstate[]=nullptr) :
  287. integrity_constraint_violation{err, Q, sqlstate} {}
  288. };
  289. class PQXX_LIBEXPORT unique_violation :
  290. public integrity_constraint_violation
  291. {
  292. public:
  293. explicit unique_violation(
  294. const std::string &err,
  295. const std::string &Q="",
  296. const char sqlstate[]=nullptr) :
  297. integrity_constraint_violation{err, Q, sqlstate} {}
  298. };
  299. class PQXX_LIBEXPORT check_violation :
  300. public integrity_constraint_violation
  301. {
  302. public:
  303. explicit check_violation(
  304. const std::string &err,
  305. const std::string &Q="",
  306. const char sqlstate[]=nullptr) :
  307. integrity_constraint_violation{err, Q, sqlstate} {}
  308. };
  309. class PQXX_LIBEXPORT invalid_cursor_state : public sql_error
  310. {
  311. public:
  312. explicit invalid_cursor_state(
  313. const std::string &err,
  314. const std::string &Q="",
  315. const char sqlstate[]=nullptr) :
  316. sql_error{err, Q, sqlstate} {}
  317. };
  318. class PQXX_LIBEXPORT invalid_sql_statement_name : public sql_error
  319. {
  320. public:
  321. explicit invalid_sql_statement_name(
  322. const std::string &err,
  323. const std::string &Q="",
  324. const char sqlstate[]=nullptr) :
  325. sql_error{err, Q, sqlstate} {}
  326. };
  327. class PQXX_LIBEXPORT invalid_cursor_name : public sql_error
  328. {
  329. public:
  330. explicit invalid_cursor_name(
  331. const std::string &err,
  332. const std::string &Q="",
  333. const char sqlstate[]=nullptr) :
  334. sql_error{err, Q, sqlstate} {}
  335. };
  336. class PQXX_LIBEXPORT syntax_error : public sql_error
  337. {
  338. public:
  339. /// Approximate position in string where error occurred, or -1 if unknown.
  340. const int error_position;
  341. explicit syntax_error(
  342. const std::string &err,
  343. const std::string &Q="",
  344. const char sqlstate[]=nullptr,
  345. int pos=-1) :
  346. sql_error{err, Q, sqlstate}, error_position{pos} {}
  347. };
  348. class PQXX_LIBEXPORT undefined_column : public syntax_error
  349. {
  350. public:
  351. explicit undefined_column(
  352. const std::string &err,
  353. const std::string &Q="",
  354. const char sqlstate[]=nullptr) :
  355. syntax_error{err, Q, sqlstate} {}
  356. };
  357. class PQXX_LIBEXPORT undefined_function : public syntax_error
  358. {
  359. public:
  360. explicit undefined_function(
  361. const std::string &err,
  362. const std::string &Q="",
  363. const char sqlstate[]=nullptr) :
  364. syntax_error{err, Q, sqlstate} {}
  365. };
  366. class PQXX_LIBEXPORT undefined_table : public syntax_error
  367. {
  368. public:
  369. explicit undefined_table(
  370. const std::string &err,
  371. const std::string &Q="",
  372. const char sqlstate[]=nullptr) :
  373. syntax_error{err, Q, sqlstate} {}
  374. };
  375. class PQXX_LIBEXPORT insufficient_privilege : public sql_error
  376. {
  377. public:
  378. explicit insufficient_privilege(
  379. const std::string &err,
  380. const std::string &Q="",
  381. const char sqlstate[]=nullptr) :
  382. sql_error{err, Q, sqlstate} {}
  383. };
  384. /// Resource shortage on the server
  385. class PQXX_LIBEXPORT insufficient_resources : public sql_error
  386. {
  387. public:
  388. explicit insufficient_resources(
  389. const std::string &err,
  390. const std::string &Q="",
  391. const char sqlstate[]=nullptr) :
  392. sql_error{err,Q, sqlstate} {}
  393. };
  394. class PQXX_LIBEXPORT disk_full : public insufficient_resources
  395. {
  396. public:
  397. explicit disk_full(
  398. const std::string &err,
  399. const std::string &Q="",
  400. const char sqlstate[]=nullptr) :
  401. insufficient_resources{err, Q, sqlstate} {}
  402. };
  403. class PQXX_LIBEXPORT out_of_memory : public insufficient_resources
  404. {
  405. public:
  406. explicit out_of_memory(
  407. const std::string &err,
  408. const std::string &Q="",
  409. const char sqlstate[]=nullptr) :
  410. insufficient_resources{err, Q, sqlstate} {}
  411. };
  412. class PQXX_LIBEXPORT too_many_connections : public broken_connection
  413. {
  414. public:
  415. explicit too_many_connections(const std::string &err) :
  416. broken_connection{err} {}
  417. };
  418. /// PL/pgSQL error
  419. /** Exceptions derived from this class are errors from PL/pgSQL procedures.
  420. */
  421. class PQXX_LIBEXPORT plpgsql_error : public sql_error
  422. {
  423. public:
  424. explicit plpgsql_error(
  425. const std::string &err,
  426. const std::string &Q="",
  427. const char sqlstate[]=nullptr) :
  428. sql_error{err, Q, sqlstate} {}
  429. };
  430. /// Exception raised in PL/pgSQL procedure
  431. class PQXX_LIBEXPORT plpgsql_raise : public plpgsql_error
  432. {
  433. public:
  434. explicit plpgsql_raise(
  435. const std::string &err,
  436. const std::string &Q="",
  437. const char sqlstate[]=nullptr) :
  438. plpgsql_error{err, Q, sqlstate} {}
  439. };
  440. class PQXX_LIBEXPORT plpgsql_no_data_found : public plpgsql_error
  441. {
  442. public:
  443. explicit plpgsql_no_data_found(
  444. const std::string &err,
  445. const std::string &Q="",
  446. const char sqlstate[]=nullptr) :
  447. plpgsql_error{err, Q, sqlstate} {}
  448. };
  449. class PQXX_LIBEXPORT plpgsql_too_many_rows : public plpgsql_error
  450. {
  451. public:
  452. explicit plpgsql_too_many_rows(
  453. const std::string &err,
  454. const std::string &Q="",
  455. const char sqlstate[]=nullptr) :
  456. plpgsql_error{err, Q, sqlstate} {}
  457. };
  458. /**
  459. * @}
  460. */
  461. }
  462. #include "pqxx/compiler-internal-post.hxx"
  463. #endif