`DatabaseSessionLogWriter.dispose` throws `ArgumentError` when an in-flight log write fails

Đang mở Phù hợp với người mới
#5,954 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
76/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
dart, flutter
Lĩnh vực
backend, databases

Hướng nghiên cứu

Đọc database_session_log_writer.dart quanh logic drain ở dòng 50 và theo dõi cách _track<T> lưu các future từ open(). Trước tiên, tái hiện lỗi typed-future bằng đoạn Dart trong issue, sau đó kiểm tra các bài test hiện có của writer về hành vi khi shutdown. Hoàn thành khi dispose() chờ đến hết thời gian drain timeout, bỏ qua các lần ghi thất bại và xóa _internalSession mà không ném lỗi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

area: database bug
Describe the bug

DatabaseSessionLogWriter.dispose() throws instead of draining when a tracked session-log write fails during shutdown. Serverpod then logs "Error draining database log writer" and keeps it as the shutdown error.

ERROR: Error draining database log writer
Invalid argument(s) (onError): The error handler of Future.catchError must return a value of the future's type
#0      _FutureListener.handleError (dart:async/future_impl.dart:262:7)
To reproduce

In a server, stop the database while sessions are being logged, then shut down.

On plain Dart, it happens on the following cases:

final Set<Future<Object?>> inflight = {Future<int>.error(StateError('connection closed'))};
await Future.wait(inflight.map((f) => f.catchError((_) => null))); // throws ArgumentError
Expected behavior

dispose() waits for in-flight writes, up to its drain timeout, and ignores their failures.

Library version

Serverpod 4.1.0

Platform information

Dart 3.12.2, Linux (WSL)

Additional context

The cause is that _inflight is a Set<Future<Object?>>, but _track<T> stores the original Future<T>, and open() tracks the Future<int> from _insertOpenRow. dispose() drains with f.catchError((_) => null) (database_session_log_writer.dart:50, from #4961). catchError checks the handler's value against the future's runtime type, and null is not an int. So the drain future fails with ArgumentError, Future.wait rethrows it, and dispose() throws before it clears _internalSession.

Fixing might be as simple as changing the code to:

final pending = _inflight
    .map((f) => f.then<void>((_) {}, onError: (_) {}))
    .toList();
How experienced are you with this library?

Expert - Experienced and comfortable with using this library in complex projects

Are you interested in working on a PR for this?
  • I want to work on this
Ngôn ngữ chính
Dart
Star
3.3k
Fork
382
Merge trung bình
1 ngày 21 giờ
Pull request đã merge (30 ngày)
47

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của serverpod/serverpod

Tất cả issue của serverpod/serverpod

Issue tương tự

Thêm issue về Dart

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.