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 * - NonSingleColumnResultSet
124 * - NonSingleRowResultSet
125 * - NoBinaryParser
126 * - RowIndexOutOfBounds
127 * - TypeCannotBeNull
128 * - UnknownBufferCategory
129 * - UserTypeError
130 * - CompositeSizeMismatch
131 * - CompositeMemberTypeMismatch
132 * - ArrayError
133 * - DimensionMismatch
134 * - InvalidDimensions
135 * - NumericError
136 * - NumericOverflow
137 * - ValueIsNaN
138 * - InvalidRepresentation
139 * - InvalidInputFormat
140 * - EnumerationError
141 * - InvalidEnumerationLiteral
142 * - InvalidEnumerationValue
143 * - TransactionError
144 * - AlreadyInTransaction
145 * - NotInTransaction
146 * - UnsupportedInterval
147 * - BoundedRangeError
148 * - BitStringError
149 * - BitStringOverflow
150 * - InvalidBitStringRepresentation
151 * - RuntimeError
152 * - ConnectionError
153 * - ClusterUnavailable
154 * - CommandError
155 * - ConnectionFailed
156 * - ServerConnectionError (contains a message from server)
157 * - ConnectionTimeoutError
158 * - ConnectionBusy
159 * - ConnectionInterrupted
160 * - PoolError
161 * - ClusterError
162 * - InvalidConfig
163 * - InvalidDSN
164 *
165 *
166 * ----------
167 *
168 * @htmlonly <div class="bottom-nav"> @endhtmlonly
169 * ⇦ @ref pg_user_row_types | @ref pg_topology ⇨
170 * @htmlonly </div> @endhtmlonly
171 */
172
173//@{
174/** @name Generic driver errors */
175
176/// @brief Base class for all exceptions that may be thrown by the driver.
177class Error : public std::runtime_error {
178 using runtime_error::runtime_error;
179};
180
181/// @brief Base Postgres logic error.
182/// Reports errors that are consequences of erroneous driver usage,
183/// such as invalid query syntax, absence of appropriate parsers, out of range
184/// errors etc.
185/// These can be avoided by fixing code.
186class LogicError : public Error {
187 using Error::Error;
188};
189
190/// @brief Base Postgres runtime error.
191/// Reports errors that are consequences of erroneous data, misconfiguration,
192/// network errors etc.
193class RuntimeError : public Error {
194 using Error::Error;
195};
196
197/// @brief Error that was reported by PosgtreSQL server
198/// Contains the message sent by the server.
199/// Templated class because the errors can be both runtime and logic.
200template <typename Base>
201class ServerError : public Base {
202public:
203 explicit ServerError(const Message& msg) : Base(msg.GetMessage()), msg_{msg} {}
204
205 const Message& GetServerMessage() const { return msg_; }
206
207 Message::Severity GetSeverity() const { return msg_.GetSeverity(); }
208 SqlState GetSqlState() const { return msg_.GetSqlState(); }
209
210private:
211 Message msg_;
212};
213
214using ServerLogicError = ServerError<LogicError>;
215using ServerRuntimeError = ServerError<RuntimeError>;
216//@}
217
218//@{
219/** @name Connection errors */
221 using RuntimeError::RuntimeError;
222};
223
224/// @brief Exception is thrown when a single connection fails to connect
226public:
227 explicit ConnectionFailed(const Dsn& dsn);
228 ConnectionFailed(const Dsn& dsn, std::string_view message);
229};
230
231/// @brief Connection error reported by PostgreSQL server.
232/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
233/// Class 08 - Connection exception
235 using ServerError::ServerError;
236};
237
238/// @brief Indicates errors during pool operation
239class PoolError : public RuntimeError {
240public:
241 PoolError(std::string_view msg, std::string_view db_name);
242 PoolError(std::string_view msg);
243};
244
246 using ConnectionError::ConnectionError;
247};
248
249/// @brief Error when invoking a libpq function
251 using ConnectionError::ConnectionError;
252};
253
254/// @brief A network operation on a connection has timed out
256 using ConnectionError::ConnectionError;
257};
258
260 using RuntimeError::RuntimeError;
261};
262
263/// @brief An attempt to make a query to server was made while there is another
264/// query in flight.
266 using RuntimeError::RuntimeError;
267};
268
269/// @brief A network operation was interrupted by task cancellation.
271 using RuntimeError::RuntimeError;
272};
273
274//@}
275
276//@{
277/** @name SQL errors */
278//@{
279/** @name Class 03 — SQL Statement Not Yet Complete */
280/// A programming error, a statement is sent before other statement's results
281/// are processed.
282class SqlStatementNotYetComplete : public ServerLogicError {
283 using ServerLogicError::ServerLogicError;
284};
285//@}
286
287//@{
288/** @name Class 09 — Triggered Action Exception */
289class TriggeredActionException : public ServerRuntimeError {
290 using ServerRuntimeError::ServerRuntimeError;
291};
292//@}
293
294//@{
295/** @name Class 0A — Feature Not Supported */
296class FeatureNotSupported : public ServerLogicError {
297 using ServerLogicError::ServerLogicError;
298};
299//@}
300
301//@{
302/** @name Class 0F - Locator Exception */
303class LocatorException : public ServerRuntimeError {
304 using ServerRuntimeError::ServerRuntimeError;
305};
306//@}
307
308//@{
309/** @name Class 0L - Invalid Grantor */
310class InvalidGrantor : public ServerRuntimeError {
311 using ServerRuntimeError::ServerRuntimeError;
312};
313//@}
314
315//@{
316/** @name Class 0P - Invalid Role Specification */
317class InvalidRoleSpecification : public ServerLogicError {
318 using ServerLogicError::ServerLogicError;
319};
320//@}
321
322//@{
323/** @name Class 0Z - Diagnostics Exception */
324class DiagnosticsException : public ServerRuntimeError {
325 using ServerRuntimeError::ServerRuntimeError;
326};
327//@}
328
329//@{
330/** @name Class 21 - Cardinality Violation */
331class CardinalityViolation : public ServerLogicError {
332 using ServerLogicError::ServerLogicError;
333};
334//@}
335
336//@{
337/** @name Class 22 — Data Exception */
338/// @brief Base class for data exceptions
339/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
340class DataException : public ServerRuntimeError {
341 using ServerRuntimeError::ServerRuntimeError;
342};
343//@}
344
345//@{
346/** @name Class 23 — Integrity Constraint Violation */
347// TODO Shortcut accessors to respective message fields
348/// @brief Base class for integrity constraint violation errors.
349/// Doc: https://www.postgresql.org/docs/12/static/errcodes-appendix.html
350class IntegrityConstraintViolation : public ServerRuntimeError {
351public:
352 using ServerRuntimeError::ServerRuntimeError;
353
354 std::string GetSchema() const;
355 std::string GetTable() const;
356 std::string GetConstraint() const;
357};
358
360 using IntegrityConstraintViolation::IntegrityConstraintViolation;
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
383/// Class 27 - Triggered Data Change Violation
385 using IntegrityConstraintViolation::IntegrityConstraintViolation;
386};
387
388/// Class 44 - WITH CHECK OPTION Violation
390 using IntegrityConstraintViolation::IntegrityConstraintViolation;
391};
392//@}
393
394//@{
395/** @name Class 24 - Invalid Cursor State */
396class InvalidCursorState : public ServerRuntimeError {
397 using ServerRuntimeError::ServerRuntimeError;
398};
399//@}
400
401//@{
402/** @name Class 25 — Invalid Transaction State */
403class InvalidTransactionState : public ServerRuntimeError {
404 using ServerRuntimeError::ServerRuntimeError;
405};
406//@}
407
408//@{
409/** @name Class 26 - Invalid SQL Statement Name */
410/// This exception is thrown in case a prepared statement doesn't exist
411class InvalidSqlStatementName : public ServerRuntimeError {
412 using ServerRuntimeError::ServerRuntimeError;
413};
414//@}
415
416//@{
417/** @name Invalid object name, several classes */
418/// @brief Exception class for several Invalid * Name classes.
419/// Class 34 - Invalid Cursor Name
420/// Class 3D - Invalid Catalogue Name
421/// Class 3F - Invalid Schema Name
422/// TODO Add documentation (links) on the error classes
423/// TODO Split exception classes if needed based on documentation
424class InvalidObjectName : public ServerLogicError {
425 using ServerLogicError::ServerLogicError;
426};
427//@}
428
429//@{
430/** @name Class 28 - Invalid Authorisation Specification */
431class InvalidAuthorizationSpecification : public ServerLogicError {
432 using ServerLogicError::ServerLogicError;
433};
434//@}
435
436//@{
437/** @name Class 2B - Dependent Privilege Descriptors Still Exist */
438class DependentPrivilegeDescriptorsStillExist : public ServerRuntimeError {
439 using ServerRuntimeError::ServerRuntimeError;
440};
441//@}
442
443//@{
444/** @name Class 2D - Invalid Transaction Termination */
445class InvalidTransactionTermination : public ServerRuntimeError {
446 using ServerRuntimeError::ServerRuntimeError;
447};
448//@}
449
450//@{
451/** @name Class 38 - External Routine Exception */
452class ExternalRoutineException : public ServerRuntimeError {
453 using ServerRuntimeError::ServerRuntimeError;
454};
455//@}
456
457//@{
458/** @name Class 39 - External Routine Invocation Exception */
459class ExternalRoutineInvocationException : public ServerRuntimeError {
460 using ServerRuntimeError::ServerRuntimeError;
461};
462//@}
463
464//@{
465/** @name Class 3B - Savepoint Exception */
466class SavepointException : public ServerRuntimeError {
467 using ServerRuntimeError::ServerRuntimeError;
468};
469//@}
470
471//@{
472/** @name Class 2F — SQL Routine Exception */
473class SqlRoutineException : public ServerRuntimeError {
474 using ServerRuntimeError::ServerRuntimeError;
475};
476//@}
477
478//@{
479/** @name Class 40 — Transaction Rollback */
480class TransactionRollback : public ServerRuntimeError {
481 using ServerRuntimeError::ServerRuntimeError;
482};
483//@}
484
485//@{
486/** @name Class 42 — Syntax Error or Access Rule Violation */
487class SyntaxError : public ServerLogicError {
488 using ServerLogicError::ServerLogicError;
489};
490
491class AccessRuleViolation : public ServerLogicError {
492 using ServerLogicError::ServerLogicError;
493};
494
495class DuplicatePreparedStatement : public ServerLogicError {
496 using ServerLogicError::ServerLogicError;
497};
498
499//@}
500
501//@{
502/** @name Class 53 - Insufficient Resources */
503class InsufficientResources : public ServerRuntimeError {
504 using ServerRuntimeError::ServerRuntimeError;
505};
506//@}
507
508//@{
509/** @name Class 54 - Program Limit Exceeded */
510class ProgramLimitExceeded : public ServerRuntimeError {
511 using ServerRuntimeError::ServerRuntimeError;
512};
513//@}
514
515//@{
516/** @name Class 55 - Object Not In Prerequisite State */
517class ObjectNotInPrerequisiteState : public ServerRuntimeError {
518 using ServerRuntimeError::ServerRuntimeError;
519};
520//@}
521
522//@{
523/** @name Class 57 - Operator Intervention */
524class OperatorIntervention : public ServerRuntimeError {
525 using ServerRuntimeError::ServerRuntimeError;
526};
527
529 using OperatorIntervention::OperatorIntervention;
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//@}
548
549//@{
550/** @name Class 58 - System Error (errors external to PostgreSQL itself) */
551class SystemError : public ServerRuntimeError {
552 using ServerRuntimeError::ServerRuntimeError;
553};
554//@}
555
556//@{
557/** @name Class 72 — Snapshot Failure */
558class SnapshotFailure : public ServerRuntimeError {
559 using ServerRuntimeError::ServerRuntimeError;
560};
561//@}
562
563//@{
564/** @name Class F0 — Configuration File Error */
565class ConfigurationFileError : public ServerRuntimeError {
566 using ServerRuntimeError::ServerRuntimeError;
567};
568//@}
569
570//@{
571/** @name Class HV — Foreign Data Wrapper Error (SQL/MED) */
572class FdwError : public ServerRuntimeError {
573 using ServerRuntimeError::ServerRuntimeError;
574};
575//@}
576
577//@{
578/** @name Class P0 — PL/pgSQL Error */
579class PlPgSqlError : public ServerRuntimeError {
580 using ServerRuntimeError::ServerRuntimeError;
581};
582//@}
583
584//@{
585/** @name Class XX — Internal Error */
586class InternalServerError : public ServerRuntimeError {
587 using ServerRuntimeError::ServerRuntimeError;
588};
589//@}
590//@}
591
592//@{
593/** @name Transaction errors */
595 using LogicError::LogicError;
596};
597
599public:
600 AlreadyInTransaction();
601};
602
604public:
605 NotInTransaction();
606 NotInTransaction(const std::string& msg);
607};
608
610public:
611 TransactionForceRollback();
612 TransactionForceRollback(const std::string& msg);
613};
614
615//@}
616
617//@{
618/** @name Result set usage errors */
619
621public:
622 ResultSetError(std::string msg);
623
624 void AddMsgSuffix(std::string_view str);
625 void AddMsgPrefix(std::string_view str);
626
627 const char* what() const noexcept override;
628
629private:
630 std::string msg_;
631};
632
633/// @brief Result set has less rows than the requested row index.
635public:
636 RowIndexOutOfBounds(std::size_t index);
637};
638
639/// @brief Result set has less columns that the requested index.
641public:
642 FieldIndexOutOfBounds(std::size_t index);
643};
644
645/// @brief Result set doesn't have field with the requested name.
647public:
648 FieldNameDoesntExist(std::string_view name);
649};
650
651/// @brief Data extraction from a null field value to a non-nullable type
652/// requested.
654public:
655 template <typename T>
656 FieldValueIsNull(std::size_t field_index, std::string_view field_name, const T&)
657 : ResultSetError(fmt::format(
658 "Field #{} name `{}` C++ type `{}` value is null, forgot `std::optional`?",
659 field_index,
660 field_name,
661 compiler::GetTypeName<T>()
662 )) {}
663};
664
665/// @brief A value of a non-nullable type requested to be set null.
666/// Can occur if io::traits::IsNullable for the type is specialised as
667/// true_type, but io::traits::GetSetNull is not specialized appropriately.
669public:
670 TypeCannotBeNull(std::string_view type);
671};
672
673/// @brief Field buffer contains different category of data than expected by
674/// data parser.
676public:
677 InvalidParserCategory(std::string_view type, io::BufferCategory parser, io::BufferCategory buffer);
678};
679
680/// @brief While checking result set types, failed to determine the buffer
681/// category for a type oid.
682/// The context string is formed by the ResultSet and will have the form
683/// of 'result set field `foo` type `my_schema.bar` field `baz` array element'
685public:
686 UnknownBufferCategory(std::string_view context, Oid type_oid);
687 UnknownBufferCategory(Oid type_oid, std::string_view cpp_field_type, std::string_view cpp_composite_type);
688
689 const Oid type_oid;
690};
691
692/// @brief A field in a result set doesn't have a binary parser.
694 using ResultSetError::ResultSetError;
695};
696
697/// @brief Buffer size is invalid for a fixed-size type.
698/// Can occur when a wrong field type is requested for reply.
700 using ResultSetError::ResultSetError;
701};
702
703/// @brief Binary buffer contains invalid data.
704/// Can occur when parsing binary buffers containing multiple fields.
706public:
707 InvalidBinaryBuffer(const std::string& message);
708};
709
710/// @brief A tuple was requested to be parsed out of a row that doesn't have
711/// enough fields.
713public:
714 InvalidTupleSizeRequested(std::size_t field_count, std::size_t tuple_size);
715};
716
717/// @brief A row or result set requested to be treated as a single column, but
718/// contains more than one column.
720public:
721 NonSingleColumnResultSet(std::size_t actual_size, std::string_view type_name, std::string_view func);
722};
723
724/// @brief A result set containing a single row was expected
726public:
727 explicit NonSingleRowResultSet(std::size_t actual_size);
728};
729
730/// @brief A row was requested to be parsed based on field names/indexed,
731/// the count of names/indexes doesn't match the tuple size.
733public:
734 FieldTupleMismatch(std::size_t field_count, std::size_t tuple_size);
735};
736
737//@}
738
739//@{
740/// @brief Base error when working with mapped types
741class UserTypeError : public LogicError {
742 using LogicError::LogicError;
743};
744
745/// @brief PostgreSQL composite type has different count of members from
746/// the C++ counterpart.
748public:
749 CompositeSizeMismatch(std::size_t pg_size, std::size_t cpp_size, std::string_view cpp_type);
750};
751
752/// @brief PostgreSQL composite type has different member type that the C++
753/// mapping suggests.
755public:
756 CompositeMemberTypeMismatch(
757 std::string_view pg_type_schema,
758 std::string_view pg_type_name,
759 std::string_view field_name,
760 Oid pg_oid,
761 Oid user_oid
762 );
763};
764
765//@}
766
767//@{
768/** @name Array errors */
769/// @brief Base error when working with array types.
770class ArrayError : public LogicError {
771 using LogicError::LogicError;
772};
773
774/// @brief Array received from postgres has different dimensions from those of
775/// C++ container.
777public:
778 DimensionMismatch();
779};
780
782public:
783 InvalidDimensions(std::size_t expected, std::size_t actual);
784};
785
786//@}
787
788//@{
789/** @name Numeric/decimal datatype errors */
790class NumericError : public LogicError {
791 using LogicError::LogicError;
792};
793
794/// Value in PostgreSQL binary buffer cannot be represented by a given C++ type
796 using NumericError::NumericError;
797};
798
799/// PostgreSQL binary buffer contains NaN value, but the given C++ type doesn't
800/// support NaN value
801class ValueIsNaN : public NumericError {
802 using NumericError::NumericError;
803};
804
805/// Integral representation for a numeric contains invalid data
807 using NumericError::NumericError;
808};
809//@}
810
811/// @brief Invalid format for input data.
812///
813/// Can occur when a numeric string representation cannot be parsed for sending
814/// in binary buffers
816 using LogicError::LogicError;
817};
818
819//@{
820/** @name Enumeration type errors */
822 using LogicError::LogicError;
823};
824
826public:
827 InvalidEnumerationLiteral(std::string_view type_name, std::string_view literal);
828};
829
831public:
832 template <typename Enum>
833 explicit InvalidEnumerationValue(Enum val)
834 : EnumerationError(fmt::format(
835 "Invalid enumeration value '{}' for enum type '{}'",
836 USERVER_NAMESPACE::utils::UnderlyingValue(val),
837 compiler::GetTypeName<Enum>()
838 )) {}
839};
840//@}
841
842/// PostgreSQL interval datatype contains months field, which cannot be
843/// converted to microseconds unambiguously
845public:
846 UnsupportedInterval();
847};
848
849/// PostgreSQL range type has at least one end unbound
851public:
852 BoundedRangeError(std::string_view message);
853};
854
855//@{
856/** @name bit/bit varying type errors */
857
858/// @brief Base error when working with bit string types.
860public:
861 using LogicError::LogicError;
862};
863
864/// Value in PostgreSQL binary buffer cannot be represented by a given C++ type
866public:
867 BitStringOverflow(std::size_t actual, std::size_t expected);
868};
869
870/// Value in PostgreSQL binary buffer cannot be represented as bit string type
872public:
873 InvalidBitStringRepresentation();
874};
875//@}
876
877//@{
878/** @name Misc exceptions */
879class InvalidDSN : public RuntimeError {
880public:
881 InvalidDSN(std::string_view dsn, std::string_view err);
882};
883
885 using RuntimeError::RuntimeError;
886};
887
889 using LogicError::LogicError;
890};
891
892//@}
893
894//@{
895/** @name ip type errors */
897public:
898 using LogicError::LogicError;
899};
900
902public:
903 explicit IpAddressInvalidFormat(std::string_view str);
904};
905//@}
906
907} // namespace storages::postgres
908
909USERVER_NAMESPACE_END