diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ae81ce..aea58e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,14 @@ - `EncoderFn` value converter for generic Dart object -> Postgres-encoded bytes (for values where type is not specified). - `DatabaseInfo` tracks information about relations and oids (currently limited to `RelationMessage` caching). -- **Behaviour / soft-breaking changes**: +- **Behaviour changes**, may be breaking in some cases: - Preparing/executing a stamement on the main connection while in a `runTx` callback will throw an exception. - Setting `timeout` will try to actively cancel the current statement using a new connection. + - `ServerException` may be transformed into `_PgQueryCancelledException` which is both `PgException` and `TimeoutException` (but no longer `ServerException`). +- **API deprecations**: - Deprecated `TupleDataColumn.data`, use `.value` instead (for binary protocol messages). - Deprecated some logical replication message parsing method. - Removed `@internal`-annotated methods from the public API of `ServerException` and `Severity`. - - `ServerException` may be transformed into `_PgTimeoutException` which is both `PgException` and `TimeoutException` (but no longer `ServerException`). ## 3.3.0 diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart index 1d61a12..4413362 100644 --- a/lib/src/exceptions.dart +++ b/lib/src/exceptions.dart @@ -190,27 +190,23 @@ ServerException buildExceptionFromErrorFields(List errorFields) { ); } -PgException transformServerException( - ServerException ex, { - bool timeoutTriggered = false, -}) { - if (ex.code == '57014' && - ex.message == 'canceling statement due to statement timeout') { - return _PgTimeoutException( - ['${ex.code}:', ex.message, ex.trace].whereType().join(' '), - ); - } - if (ex.code == '57014' && timeoutTriggered) { - return _PgTimeoutException( +PgException transformServerException(ServerException ex) { + if (ex.code == '57014') { + return _PgQueryCancelledException( ['${ex.code}:', ex.message, ex.trace].whereType().join(' '), + severity: ex.severity, ); } return ex; } -class _PgTimeoutException extends PgException implements TimeoutException { +class _PgQueryCancelledException extends PgException + implements TimeoutException { @override late final duration = null; - _PgTimeoutException(super.message) : super(severity: Severity.error); + _PgQueryCancelledException( + super.message, { + required super.severity, + }); } diff --git a/lib/src/v3/connection.dart b/lib/src/v3/connection.dart index 088b247..8e406cf 100644 --- a/lib/src/v3/connection.dart +++ b/lib/src/v3/connection.dart @@ -892,11 +892,9 @@ class _PgResultStreamSubscription required List items, required Duration? timeout, }) async { - bool timeoutTriggered = false; final cancelTimer = timeout == null ? null : Timer(timeout, () async { - timeoutTriggered = true; await connection.cancelPendingStatement(); }); try { @@ -906,11 +904,6 @@ class _PgResultStreamSubscription affectedRows: await affectedRows, schema: await schema, ); - } on ServerException catch (e) { - if (timeoutTriggered) { - throw transformServerException(e, timeoutTriggered: timeoutTriggered); - } - rethrow; } finally { cancelTimer?.cancel(); } diff --git a/test/timeout_test.dart b/test/timeout_test.dart index a6f7e20..3d9e4c5 100644 --- a/test/timeout_test.dart +++ b/test/timeout_test.dart @@ -22,7 +22,15 @@ void main() { test('Cancel current statement through a new connection', () async { final f = conn.execute('SELECT pg_sleep(2);'); await (conn as PgConnectionImplementation).cancelPendingStatement(); - await expectLater(f, throwsA(isA())); + await expectLater( + f, + throwsA( + allOf( + isA(), + isA(), + ), + ), + ); // connection is still usable final rs = await conn.execute('SELECT 1;'); expect(rs[0][0], 1);