userver: userver/storages/postgres/exceptions.hpp Source File
Loading...
Searching...
No Matches
exceptions.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/exceptions.hpp
4/// @brief Postgres errors
5
6#include <optional>
7#include <stdexcept>
8#include <string_view>
9
10#include <fmt/format.h>
11
12#include <userver/storages/postgres/dsn.hpp>
13#include <userver/storages/postgres/io/traits.hpp>
14#include <userver/storages/postgres/message.hpp>
15
16#include <userver/compiler/demangle.hpp>
17#include <userver/utils/underlying_value.hpp>
18
19USERVER_NAMESPACE_BEGIN
20
21namespace storages::postgres {
22
23namespace impl {
24
25// Provides nice to read messages for pattern strings that end on 'type'. For example:
26// fmt::format("Unexpected database type {}", OidPrettyPrint(oid));
27std::string OidPrettyPrint(Oid oid);
28
29} // namespace impl
30
31/**
32 * @page pg_errors uPg: Postgres errors
33 *
34 * Base class for all PostgreSQL errors is Error which is derived from
35 * std::runtime_error. This is done to simplify exception handling.
36 *
37 * There are two base types of errors: runtime (RuntimeError) and logic
38 * (LogicError).
39 *
40 * **Logic errors** are a consequence of faulty logic within the program such as
41 * violating logical preconditions or invariants and may be preventable by
42 * correcting the program.
43 *
44 * **Runtime errors** are due to events beyond the scope of the program, such as
45 * network failure, faulty configuration file, unique index violation etc. A
46 * user can catch such an error and recover from it by reconnecting, providing
47 * a decent default for configuration or modifying the key value.
48 *
49 * Both logic and runtime errors can contain a postgres server message
50 * (Message). Those are ServerLogicError and ServerRuntimeError
51 * respectively. These errors occur on the server side and are translated into
52 * exceptions by the driver. Server errors are descendants of either
53 * ServerLogicError or ServerRuntimeError and their hierarchy corresponds to SQL
54 * error classes.
55 *
56 * Some server errors, such as IntegrityConstraintViolation, have a more
57 * detailed hierarchy to distinguish errors in catch clauses.
58 *
59 * Server errors have the following hierarchy:
60 * - ServerLogicError
61 * - SqlStatementNotYetComplete
62 * - FeatureNotSupported
63 * - InvalidRoleSpecification
64 * - CardinalityViolation
65 * - InvalidObjectName
66 * - InvalidAuthorizationSpecification
67 * - SyntaxError
68 * - AccessRuleViolation
69 * - ServerRuntimeError
70 * - TriggeredActionException
71 * - LocatorException
72 * - InvalidGrantor
73 * - DiagnosticsException
74 * - DataException
75 * - DuplicatePreparedStatement
76 * - IntegrityConstraintViolation
77 * - RestrictViolation
78 * - NotNullViolation (TODO Make it a logic error)
79 * - ForeignKeyViolation
80 * - UniqueViolation
81 * - CheckViolation
82 * - ExclusionViolation
83 * - TriggeredDataChangeViolation
84 * - WithCheckOptionViolation
85 * - InvalidCursorState
86 * - InvalidSqlStatementName
87 * - InvalidTransactionState
88 * - DependentPrivilegeDescriptorsStillExist
89 * - InvalidTransactionTermination
90 * - ExternalRoutineException
91 * - ExternalRoutineInvocationException
92 * - SavepointException
93 * - SqlRoutineException
94 * - TransactionRollback
95 * - InsufficientResources
96 * - ProgramLimitExceeded
97 * - ObjectNotInPrerequisiteState
98 * - OperatorIntervention
99 * - QueryCancelled
100 * - AdminShutdown
101 * - CrashShutdown
102 * - CannotConnectNow
103 * - DatabaseDropped
104 * - SystemError
105 * - SnapshotFailure
106 * - ConfigurationFileError
107 * - FdwError
108 * - PlPgSqlError
109 * - InternalServerError
110 *
111 * Besides server errors there are exceptions thrown by the driver itself,
112 * those are:
113 * - LogicError
114 * - ResultSetError
115 * - FieldIndexOutOfBounds
116 * - FieldNameDoesntExist
117 * - FieldTupleMismatch
118 * - FieldValueIsNull
119 * - InvalidBinaryBuffer
120 * - InvalidInputBufferSize
121 * - InvalidParserCategory
122 * - InvalidTupleSizeRequested
123 * - NarrowingOverflow
124 * - NonSingleColumnResultSet
125 * - NonSingleRowResultSet
126 * - NoBinaryParser
127 * - RowIndexOutOfBounds
128 * - TypeCannotBeNull
129 * - UnknownBufferCategory
130 * - UserTypeError
131 * - CompositeSizeMismatch
132 * - CompositeMemberTypeMismatch
133 * - ArrayError
134 * - DimensionMismatch
135 * - InvalidDimensions
136 * - NumericError
137 * - NumericOverflow
138 * - ValueIsNaN
139 * - InvalidRepresentation
140 * - InvalidInputFormat
141 * - EnumerationError
142 * - InvalidEnumerationLiteral
143 * - InvalidEnumerationValue
144 * - TransactionError
145 * - AlreadyInTransaction
146 * - NotInTransaction
147 * - UnsupportedInterval
148 * - BoundedRangeError
149 * - BitStringError
150 * - BitStringOverflow
151 * - InvalidBitStringRepresentation
152 * - RuntimeError
153 * - ConnectionError
154 * - ClusterUnavailable
155 * - CommandError
156 * - ConnectionFailed
157 * - ServerConnectionError (contains a message from server)
158 * - ConnectionTimeoutError
159 * - ConnectionBusy
160 * - ConnectionInterrupted
161 * - PoolError
162 * - ClusterError
163 * - InvalidConfig
164 * - InvalidDSN
165 *
166 *
167 * ----------
168 *
169 * @htmlonly <div class="bottom-nav"> @endhtmlonly
170 * ⇦ @ref pg_user_row_types | @ref pg_topology ⇨
171 * @htmlonly </div> @endhtmlonly
172 */
173
174//@{
175/** @name Generic driver errors */
176
177/// @brief Base class for all exceptions that may be thrown by the driver.
178class Error : public std::runtime_error {
179 using runtime_error::runtime_error;
180};
181
182/// @brief Base Postgres logic error.
183/// Reports errors that are consequences of erroneous driver usage,
184/// such as invalid query syntax, absence of appropriate parsers, out of range
185/// errors etc.
186/// These can be avoided by fixing code.
187class LogicError : public Error {
188 using Error::Error;
189};
190
191/// @brief Base Postgres runtime error.
192/// Reports errors that are consequences of erroneous data, misconfiguration,
193/// network errors etc.
194class RuntimeError : public Error {
195 using Error::Error;
196};
197
198/// @brief Error that was reported by PosgtreSQL server
199/// Contains the message sent by the server.
200/// Templated class because the errors can be both runtime and logic.
201template <typename Base>
202class ServerError : public Base {
203public:
204 explicit ServerError(const Message& msg)
205 : Base(msg.GetMessage()),
206 msg_{msg}
207 {}
208
209 const Message& GetServerMessage() const { return msg_; }
210
211 Message::Severity GetSeverity() const { return msg_.GetSeverity(); }
212 SqlState GetSqlState() const { return msg_.GetSqlState(); }
213
214private:
215 Message msg_;
216};
217
218using ServerLogicError = ServerError<LogicError>;
219using ServerRuntimeError = ServerError<RuntimeError>;
220//@}
221
222//@{
223/** @name Connection errors */
225 using RuntimeError::RuntimeError;
226};
227
228/// @brief Exception is thrown when a single connection fails to connect
230public:
231 explicit ConnectionFailed(const Dsn& dsn);
232 ConnectionFailed(const Dsn& dsn, std::string_view message);
233};
234
235/// @brief Connection error reported by PostgreSQL server.
236/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
237/// Class 08 - Connection exception
239 using ServerError::ServerError;
240};
241
242/// @brief Indicates errors during pool operation
243class PoolError : public RuntimeError {
244public:
245 PoolError(std::string_view msg, std::string_view db_name);
246 PoolError(std::string_view msg);
247};
248
250 using ConnectionError::ConnectionError;
251};
252
253/// @brief Error when invoking a libpq function
255 using ConnectionError::ConnectionError;
256};
257
258/// @brief A network operation on a connection has timed out
260 using ConnectionError::ConnectionError;
261};
262
264 using RuntimeError::RuntimeError;
265};
266
267/// @brief An attempt to make a query to server was made while there is another
268/// query in flight.
270 using RuntimeError::RuntimeError;
271};
272
273/// @brief A network operation was interrupted by task cancellation.
275 using RuntimeError::RuntimeError;
276};
277
278//@}
279
280//@{
281/** @name SQL errors */
282//@{
283/** @name Class 03 — SQL Statement Not Yet Complete */
284/// A programming error, a statement is sent before other statement's results
285/// are processed.
286class SqlStatementNotYetComplete : public ServerLogicError {
287 using ServerLogicError::ServerLogicError;
288};
289//@}
290
291//@{
292/** @name Class 09 — Triggered Action Exception */
293class TriggeredActionException : public ServerRuntimeError {
294 using ServerRuntimeError::ServerRuntimeError;
295};
296//@}
297
298//@{
299/** @name Class 0A — Feature Not Supported */
300class FeatureNotSupported : public ServerLogicError {
301 using ServerLogicError::ServerLogicError;
302};
303//@}
304
305//@{
306/** @name Class 0F - Locator Exception */
307class LocatorException : public ServerRuntimeError {
308 using ServerRuntimeError::ServerRuntimeError;
309};
310//@}
311
312//@{
313/** @name Class 0L - Invalid Grantor */
314class InvalidGrantor : public ServerRuntimeError {
315 using ServerRuntimeError::ServerRuntimeError;
316};
317//@}
318
319//@{
320/** @name Class 0P - Invalid Role Specification */
321class InvalidRoleSpecification : public ServerLogicError {
322 using ServerLogicError::ServerLogicError;
323};
324//@}
325
326//@{
327/** @name Class 0Z - Diagnostics Exception */
328class DiagnosticsException : public ServerRuntimeError {
329 using ServerRuntimeError::ServerRuntimeError;
330};
331//@}
332
333//@{
334/** @name Class 21 - Cardinality Violation */
335class CardinalityViolation : public ServerLogicError {
336 using ServerLogicError::ServerLogicError;
337};
338//@}
339
340//@{
341/** @name Class 22 — Data Exception */
342/// @brief Base class for data exceptions
343/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
344class DataException : public ServerRuntimeError {
345 using ServerRuntimeError::ServerRuntimeError;
346};
347//@}
348
349//@{
350/** @name Class 23 — Integrity Constraint Violation */
351// TODO Shortcut accessors to respective message fields
352/// @brief Base class for integrity constraint violation errors.
353/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
354class IntegrityConstraintViolation : public ServerRuntimeError {
355public:
356 using ServerRuntimeError::ServerRuntimeError;
357
358 std::string GetSchema() const;
359 std::string GetTable() const;
360 std::string GetConstraint() const;
361};
362
364 using IntegrityConstraintViolation::IntegrityConstraintViolation;
365};
366
368 using IntegrityConstraintViolation::IntegrityConstraintViolation;
369};
370
372 using IntegrityConstraintViolation::IntegrityConstraintViolation;
373};
374
376 using IntegrityConstraintViolation::IntegrityConstraintViolation;
377};
378
380 using IntegrityConstraintViolation::IntegrityConstraintViolation;
381};
382
384 using IntegrityConstraintViolation::IntegrityConstraintViolation;
385};
386
387/// Class 27 - Triggered Data Change Violation
389 using IntegrityConstraintViolation::IntegrityConstraintViolation;
390};
391
392/// Class 44 - WITH CHECK OPTION Violation
394 using IntegrityConstraintViolation::IntegrityConstraintViolation;
395};
396//@}
397
398//@{
399/** @name Class 24 - Invalid Cursor State */
400class InvalidCursorState : public ServerRuntimeError {
401 using ServerRuntimeError::ServerRuntimeError;
402};
403//@}
404
405//@{
406/** @name Class 25 — Invalid Transaction State */
407class InvalidTransactionState : public ServerRuntimeError {
408 using ServerRuntimeError::ServerRuntimeError;
409};
410//@}
411
412//@{
413/** @name Class 26 - Invalid SQL Statement Name */
414/// This exception is thrown in case a prepared statement doesn't exist
415class InvalidSqlStatementName : public ServerRuntimeError {
416 using ServerRuntimeError::ServerRuntimeError;
417};
418//@}
419
420//@{
421/** @name Invalid object name, several classes */
422/// @brief Exception class for several Invalid * Name classes.
423/// Class 34 - Invalid Cursor Name
424/// Class 3D - Invalid Catalogue Name
425/// Class 3F - Invalid Schema Name
426/// TODO Add documentation (links) on the error classes
427/// TODO Split exception classes if needed based on documentation
428class InvalidObjectName : public ServerLogicError {
429 using ServerLogicError::ServerLogicError;
430};
431//@}
432
433//@{
434/** @name Class 28 - Invalid Authorisation Specification */
435class InvalidAuthorizationSpecification : public ServerLogicError {
436 using ServerLogicError::ServerLogicError;
437};
438//@}
439
440//@{
441/** @name Class 2B - Dependent Privilege Descriptors Still Exist */
442class DependentPrivilegeDescriptorsStillExist : public ServerRuntimeError {
443 using ServerRuntimeError::ServerRuntimeError;
444};
445//@}
446
447//@{
448/** @name Class 2D - Invalid Transaction Termination */
449class InvalidTransactionTermination : public ServerRuntimeError {
450 using ServerRuntimeError::ServerRuntimeError;
451};
452//@}
453
454//@{
455/** @name Class 38 - External Routine Exception */
456class ExternalRoutineException : public ServerRuntimeError {
457 using ServerRuntimeError::ServerRuntimeError;
458};
459//@}
460
461//@{
462/** @name Class 39 - External Routine Invocation Exception */
463class ExternalRoutineInvocationException : public ServerRuntimeError {
464 using ServerRuntimeError::ServerRuntimeError;
465};
466//@}
467
468//@{
469/** @name Class 3B - Savepoint Exception */
470class SavepointException : public ServerRuntimeError {
471 using ServerRuntimeError::ServerRuntimeError;
472};
473//@}
474
475//@{
476/** @name Class 2F — SQL Routine Exception */
477class SqlRoutineException : public ServerRuntimeError {
478 using ServerRuntimeError::ServerRuntimeError;
479};
480//@}
481
482//@{
483/** @name Class 40 — Transaction Rollback */
484class TransactionRollback : public ServerRuntimeError {
485 using ServerRuntimeError::ServerRuntimeError;
486};
487//@}
488
489//@{
490/** @name Class 42 — Syntax Error or Access Rule Violation */
491class SyntaxError : public ServerLogicError {
492 using ServerLogicError::ServerLogicError;
493};
494
495class AccessRuleViolation : public ServerLogicError {
496 using ServerLogicError::ServerLogicError;
497};
498
499class DuplicatePreparedStatement : public ServerLogicError {
500 using ServerLogicError::ServerLogicError;
501};
502
503//@}
504
505//@{
506/** @name Class 53 - Insufficient Resources */
507class InsufficientResources : public ServerRuntimeError {
508 using ServerRuntimeError::ServerRuntimeError;
509};
510//@}
511
512//@{
513/** @name Class 54 - Program Limit Exceeded */
514class ProgramLimitExceeded : public ServerRuntimeError {
515 using ServerRuntimeError::ServerRuntimeError;
516};
517//@}
518
519//@{
520/** @name Class 55 - Object Not In Prerequisite State */
521class ObjectNotInPrerequisiteState : public ServerRuntimeError {
522 using ServerRuntimeError::ServerRuntimeError;
523};
524//@}
525
526//@{
527/** @name Class 57 - Operator Intervention */
528class OperatorIntervention : public ServerRuntimeError {
529 using ServerRuntimeError::ServerRuntimeError;
530};
531
533 using OperatorIntervention::OperatorIntervention;
534};
535
537 using OperatorIntervention::OperatorIntervention;
538};
539
541 using OperatorIntervention::OperatorIntervention;
542};
543
545 using OperatorIntervention::OperatorIntervention;
546};
547
549 using OperatorIntervention::OperatorIntervention;
550};
551//@}
552
553//@{
554/** @name Class 58 - System Error (errors external to PostgreSQL itself) */
555class SystemError : public ServerRuntimeError {
556 using ServerRuntimeError::ServerRuntimeError;
557};
558//@}
559
560//@{
561/** @name Class 72 — Snapshot Failure */
562class SnapshotFailure : public ServerRuntimeError {
563 using ServerRuntimeError::ServerRuntimeError;
564};
565//@}
566
567//@{
568/** @name Class F0 — Configuration File Error */
569class ConfigurationFileError : public ServerRuntimeError {
570 using ServerRuntimeError::ServerRuntimeError;
571};
572//@}
573
574//@{
575/** @name Class HV — Foreign Data Wrapper Error (SQL/MED) */
576class FdwError : public ServerRuntimeError {
577 using ServerRuntimeError::ServerRuntimeError;
578};
579//@}
580
581//@{
582/** @name Class P0 — PL/pgSQL Error */
583class PlPgSqlError : public ServerRuntimeError {
584 using ServerRuntimeError::ServerRuntimeError;
585};
586//@}
587
588//@{
589/** @name Class XX — Internal Error */
590class InternalServerError : public ServerRuntimeError {
591 using ServerRuntimeError::ServerRuntimeError;
592};
593//@}
594//@}
595
596//@{
597/** @name Transaction errors */
599 using LogicError::LogicError;
600};
601
603public:
604 AlreadyInTransaction();
605};
606
608public:
609 NotInTransaction();
610 NotInTransaction(const std::string& msg);
611};
612
614public:
615 TransactionForceRollback();
616 TransactionForceRollback(const std::string& msg);
617};
618
619//@}
620
621//@{
622/** @name Result set usage errors */
623
625public:
626 ResultSetError(std::string msg);
627
628 void AddMsgSuffix(std::string_view str);
629 void AddMsgPrefix(std::string_view str);
630
631 const char* what() const noexcept override;
632
633private:
634 std::string msg_;
635};
636
637/// @brief Result set has less rows than the requested row index.
639public:
640 RowIndexOutOfBounds(std::size_t index);
641};
642
643/// @brief Result set has less columns that the requested index.
645public:
646 FieldIndexOutOfBounds(std::size_t index);
647};
648
649/// @brief Result set doesn't have field with the requested name.
651public:
652 FieldNameDoesntExist(std::string_view name);
653};
654
655/// @brief Data extraction from a null field value to a non-nullable type
656/// requested.
658public:
659 template <typename T>
660 FieldValueIsNull(std::size_t field_index, std::string_view field_name, const T&)
661 : ResultSetError(fmt::format(
662 "Field #{} name `{}` C++ type `{}` value is null, forgot `std::optional`?",
663 field_index,
664 field_name,
665 compiler::GetTypeName<T>()
666 ))
667 {}
668};
669
670/// @brief A value of a non-nullable type requested to be set null.
671/// Can occur if io::traits::IsNullable for the type is specialised as
672/// true_type, but io::traits::GetSetNull is not specialized appropriately.
674public:
675 TypeCannotBeNull(std::string_view type);
676};
677
678/// @brief Field buffer contains different category of data than expected by
679/// data parser.
681public:
682 InvalidParserCategory(std::string_view type, io::BufferCategory parser, io::BufferCategory buffer);
683};
684
685/// @brief While checking result set types, failed to determine the buffer
686/// category for a type oid.
687/// The context string is formed by the ResultSet and will have the form
688/// of 'result set field `foo` type `my_schema.bar` field `baz` array element'
690public:
691 UnknownBufferCategory(std::string_view context, Oid type_oid);
692 UnknownBufferCategory(Oid type_oid, std::string_view cpp_field_type, std::string_view cpp_composite_type);
693
694 const Oid type_oid;
695};
696
697/// @brief A field in a result set doesn't have a binary parser.
699 using ResultSetError::ResultSetError;
700};
701
702/// @brief Buffer size is invalid for a fixed-size type.
703/// Can occur when a wrong field type is requested for reply.
705 using ResultSetError::ResultSetError;
706};
707
708/// @brief Binary buffer contains invalid data.
709/// Can occur when parsing binary buffers containing multiple fields.
711public:
712 InvalidBinaryBuffer(const std::string& message);
713};
714
715/// @brief A tuple was requested to be parsed out of a row that doesn't have
716/// enough fields.
718public:
719 InvalidTupleSizeRequested(std::size_t field_count, std::size_t tuple_size);
720};
721
722/// @brief A row or result set requested to be treated as a single column, but
723/// contains more than one column.
725public:
726 NonSingleColumnResultSet(std::size_t actual_size, std::string_view type_name, std::string_view func);
727};
728
729/// @brief A result set containing a single row was expected
731public:
732 explicit NonSingleRowResultSet(std::size_t actual_size);
733};
734
735/// @brief A row was requested to be parsed based on field names/indexed,
736/// the count of names/indexes doesn't match the tuple size.
738public:
739 FieldTupleMismatch(std::size_t field_count, std::size_t tuple_size);
740};
741
742/// @brief A binary buffer contains a numeric value that does not fit
743/// into a given C++ value type.
745public:
746 using ResultSetError::ResultSetError;
747};
748
749//@}
750
751//@{
752/// @brief Base error when working with mapped types
753class UserTypeError : public LogicError {
754 using LogicError::LogicError;
755};
756
757/// @brief PostgreSQL composite type has different count of members from
758/// the C++ counterpart.
760public:
761 CompositeSizeMismatch(std::size_t pg_size, std::size_t cpp_size, std::string_view cpp_type);
762};
763
764/// @brief PostgreSQL composite type has different member type that the C++
765/// mapping suggests.
767public:
768 CompositeMemberTypeMismatch(
769 std::string_view pg_type_schema,
770 std::string_view pg_type_name,
771 std::string_view field_name,
772 Oid pg_oid,
773 Oid user_oid
774 );
775};
776
777//@}
778
779//@{
780/** @name Array errors */
781/// @brief Base error when working with array types.
782class ArrayError : public LogicError {
783 using LogicError::LogicError;
784};
785
786/// @brief Array received from postgres has different dimensions from those of
787/// C++ container.
789public:
790 DimensionMismatch();
791};
792
794public:
795 InvalidDimensions(std::size_t expected, std::size_t actual);
796};
797
798//@}
799
800//@{
801/** @name Numeric/decimal datatype errors */
802class NumericError : public LogicError {
803 using LogicError::LogicError;
804};
805
806/// Value in PostgreSQL binary buffer cannot be represented by a given C++ type
808 using NumericError::NumericError;
809};
810
811/// PostgreSQL binary buffer contains NaN value, but the given C++ type doesn't
812/// support NaN value
813class ValueIsNaN : public NumericError {
814 using NumericError::NumericError;
815};
816
817/// Integral representation for a numeric contains invalid data
819 using NumericError::NumericError;
820};
821//@}
822
823/// @brief Invalid format for input data.
824///
825/// Can occur when a numeric string representation cannot be parsed for sending
826/// in binary buffers
828 using LogicError::LogicError;
829};
830
831//@{
832/** @name Enumeration type errors */
834 using LogicError::LogicError;
835};
836
838public:
839 InvalidEnumerationLiteral(std::string_view type_name, std::string_view literal);
840};
841
843public:
844 template <typename Enum>
845 explicit InvalidEnumerationValue(Enum val)
846 : EnumerationError(fmt::format(
847 "Invalid enumeration value '{}' for enum type '{}'",
848 USERVER_NAMESPACE::utils::UnderlyingValue(val),
849 compiler::GetTypeName<Enum>()
850 ))
851 {}
852};
853//@}
854
855/// PostgreSQL interval datatype contains months field, which cannot be
856/// converted to microseconds unambiguously
858public:
859 UnsupportedInterval();
860};
861
862/// PostgreSQL range type has at least one end unbound
864public:
865 BoundedRangeError(std::string_view message);
866};
867
868//@{
869/** @name bit/bit varying type errors */
870
871/// @brief Base error when working with bit string types.
873public:
874 using LogicError::LogicError;
875};
876
877/// Value in PostgreSQL binary buffer cannot be represented by a given C++ type
879public:
880 BitStringOverflow(std::size_t actual, std::size_t expected);
881};
882
883/// Value in PostgreSQL binary buffer cannot be represented as bit string type
885public:
886 InvalidBitStringRepresentation();
887};
888//@}
889
890//@{
891/** @name Misc exceptions */
892class InvalidDSN : public RuntimeError {
893public:
894 InvalidDSN(std::string_view dsn, std::string_view err);
895};
896
898 using RuntimeError::RuntimeError;
899};
900
902 using LogicError::LogicError;
903};
904
905//@}
906
907//@{
908/** @name ip type errors */
910public:
911 using LogicError::LogicError;
912};
913
915public:
916 explicit IpAddressInvalidFormat(std::string_view str);
917};
918//@}
919
920} // namespace storages::postgres
921
922USERVER_NAMESPACE_END