Skip to content

Commit 42059ed

Browse files
authored
add DuplicateKeyException and ForeignKeyViolationException (#416)
1 parent 7563713 commit 42059ed

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

lib/postgres.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ import 'src/v3/protocol.dart';
1515
import 'src/v3/query_description.dart';
1616

1717
export 'src/exceptions.dart'
18-
show BadCertificateException, Severity, PgException, ServerException;
18+
show
19+
BadCertificateException,
20+
Severity,
21+
PgException,
22+
ServerException,
23+
DuplicateKeyException,
24+
ForeignKeyViolationException;
1925
export 'src/pool/pool_api.dart';
2026
export 'src/replication.dart';
2127
export 'src/types.dart';
@@ -225,6 +231,7 @@ abstract class Connection implements Session, SessionExecutor {
225231
}
226232

227233
ConnectionInfo get info;
234+
228235
Channels get channels;
229236
}
230237

lib/src/exceptions.dart

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,15 @@ ServerException buildExceptionFromErrorFields(List<ErrorField> errorFields) {
191191
}
192192

193193
PgException transformServerException(ServerException ex) {
194-
if (ex.code == '57014') {
195-
return _PgQueryCancelledException(
196-
['${ex.code}:', ex.message, ex.trace].whereType<String>().join(' '),
197-
severity: ex.severity,
198-
);
199-
}
200-
return ex;
194+
return switch (ex.code) {
195+
'23505' => DuplicateKeyException(ex.message, severity: ex.severity),
196+
'23503' => ForeignKeyViolationException(ex.message, severity: ex.severity),
197+
'57014' => _PgQueryCancelledException(
198+
['${ex.code}:', ex.message, ex.trace].whereType<String>().join(' '),
199+
severity: ex.severity,
200+
),
201+
_ => ex,
202+
};
201203
}
202204

203205
class _PgQueryCancelledException extends PgException
@@ -210,3 +212,17 @@ class _PgQueryCancelledException extends PgException
210212
required super.severity,
211213
});
212214
}
215+
216+
class DuplicateKeyException extends PgException {
217+
DuplicateKeyException(
218+
super.message, {
219+
required super.severity,
220+
});
221+
}
222+
223+
class ForeignKeyViolationException extends PgException {
224+
ForeignKeyViolationException(
225+
super.message, {
226+
required super.severity,
227+
});
228+
}

test/error_handling_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,46 @@ void main() {
6767
),
6868
);
6969
});
70+
71+
test('DuplicateKeyException', () async {
72+
final c = await server.newConnection();
73+
await c.execute('CREATE TABLE test (id INT PRIMARY KEY);');
74+
await c.execute('INSERT INTO test (id) VALUES (1);');
75+
addTearDown(() async => c.execute('DROP TABLE test;'));
76+
77+
try {
78+
await c.execute('INSERT INTO test (id) VALUES (1);');
79+
} catch (e) {
80+
expect(e, isA<DuplicateKeyException>());
81+
expect(
82+
e.toString(),
83+
contains(
84+
'duplicate key value violates unique constraint "test_pkey"'));
85+
}
86+
});
87+
88+
test('ForeignKeyViolationException', () async {
89+
final c = await server.newConnection();
90+
await c.execute('CREATE TABLE test (id INT PRIMARY KEY);');
91+
await c.execute(
92+
'CREATE TABLE test2 (id INT PRIMARY KEY, test_id INT REFERENCES test(id));');
93+
await c.execute('INSERT INTO test (id) VALUES (1);');
94+
addTearDown(() async {
95+
await c.execute('DROP TABLE test2;');
96+
await c.execute('DROP TABLE test;');
97+
});
98+
99+
try {
100+
await c.execute('INSERT INTO test2 (id, test_id) VALUES (1, 2);');
101+
} catch (e) {
102+
expect(e, isA<ForeignKeyViolationException>());
103+
expect(
104+
e.toString(),
105+
contains(
106+
'insert or update on table "test2" violates foreign key constraint "test2_test_id_fkey"',
107+
),
108+
);
109+
}
110+
});
70111
});
71112
}

test/transaction_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ void main() {
700700
// ignore
701701
}
702702
}),
703-
throwsA(isA<ServerException>()),
703+
throwsA(isA<DuplicateKeyException>()),
704704
);
705705
});
706706
});

0 commit comments

Comments
 (0)