supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
703 stars 167 forks source link

Stream errors after system sleep (Desktop) #579

Open maxfornacon opened 1 year ago

maxfornacon commented 1 year ago

Describe the bug I'm experiencing an issue on Flutter desktop especially on MacOS (other platforms not properly tested yet). When the OS goes into sleep mode and awakens after a longer period of time streams seem to not be reconnecting properly.

I'm getting a couple of error messages:

First a couple of these:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:202:39)
#3      RealtimeChannel.onError.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:331:36)
#4      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#5      RealtimeClient._triggerChanError (package:realtime_client/src/realtime_client.dart:408:15)
#6      RealtimeClient._onConnClose (package:realtime_client/src/realtime_client.dart:389:7)
#7      RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:147:11)
#8      _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#9      _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#10     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#11     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#12     _ForwardingStream._handleDone (dart:async/stream_pipe.dart:99:10)
#13     _ForwardingStreamSubscription._handleDone (dart:async/stream_pipe.dart:161:13)
#14     _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#15     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#16     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#17     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#18     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:782:19)
#19     _StreamController._closeUnchecked (dart:async/stream_controller.dart:637:7)
#20     _StreamController.close (dart:async/stream_controller.dart:630:5)
#21     _RootZone.run (dart:async/zone.dart:1654:54)
#22     _FutureListener.handleWhenComplete (dart:async/future_impl.dart:190:18)
#23     Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:737:39)
#24     Future._propagateToListeners (dart:async/future_impl.dart:793:11)
#25     Future._completeWithValue (dart:async/future_impl.dart:567:5)
#26     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:640:7)
#27     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#28     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

Then there is this one:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: "{:error, [message: \"Invalid token\", claim: \"exp\", claim_val: 1690999365]}"
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:277:19)
#3      Push._matchReceive.<anonymous closure> (package:realtime_client/src/push.dart:136:17)
#4      Iterable.forEach (dart:core/iterable.dart:325:35)
#5      Push._matchReceive (package:realtime_client/src/push.dart:135:48)
#6      Push.startTimeout.<anonymous closure> (package:realtime_client/src/push.dart:99:7)
#7      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#8      new RealtimeChannel.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:171:7)
#9      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#10     RealtimeClient.onConnMessage.<anonymous closure>.<anonymous closure> (package:realtime_client/src/realtime_client.dart:310:41)
#11     Iterable.forEach (dart:core/iterable.dart:325:35)
#12     RealtimeClient.onConnMessage.<anonymous closure> (package:realtime_client/src/realtime_client.dart:310:12)
#13     new RealtimeClient.<anonymous closure> (package:realtime_client/src/realtime_client.dart:110:21)
#14     RealtimeClient.onConnMessage (package:realtime_client/src/realtime_client.dart:293:11)
#15     RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:140:22)
#16     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#17     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#18     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#19     _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
#20     _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10)
#21     _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
#22     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#23     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#24     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#25     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#26     _StreamController._add (dart:async/stream_controller.dart:648:7)
#27     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#28     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#29     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#30     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#31     _StreamController._add (dart:async/stream_controller.dart:648:7)
#32     _StreamController.add (dart:async/stream_controller.dart:596:5)
#33     new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1144:21)
#34     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#35     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#36     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#37     _SinkTransformerStreamSubscription._add (dart:async/stream_transformers.dart:63:11)
#38     _EventSinkWrapper.add (dart:async/stream_transformers.dart:13:11)
#39     _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:332:23)
#40     _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:226:46)
#41     _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)
#42     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#43     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#44     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#45     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#46     _StreamController._add (dart:async/stream_controller.dart:648:7)
#47     _StreamController.add (dart:async/stream_controller.dart:596:5)
#48     _Socket._onData (dart:io-patch/socket_patch.dart:2355:41)
#49     _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#50     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#51     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#52     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#53     _StreamController._add (dart:async/stream_controller.dart:648:7)
#54     _StreamController.add (dart:async/stream_controller.dart:596:5)
#55     _RawSecureSocket._sendReadEvent (dart:io/secure_socket.dart:1111:19)
#56     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#57     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#58     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#59     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

When I trigger a request to Supabase the token gets refreshed, which is good. All requests to Supabase seem to work fine, but streams don't.

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Cannot add event after closing
#0      _StreamController.add (dart:async/stream_controller.dart:595:24)
#1      _CompleterSink.add (package:web_socket_channel/src/sink_completer.dart:90:27)
#2      RealtimeClient.push.callback.<anonymous closure> (package:realtime_client/src/realtime_client.dart:267:55)
#3      new RealtimeClient.<anonymous closure> (package:realtime_client/src/realtime_client.dart:107:21)
#4      RealtimeClient.push.callback (package:realtime_client/src/realtime_client.dart:267:13)
#5      RealtimeClient.push (package:realtime_client/src/realtime_client.dart:284:9)
#6      Push.send (package:realtime_client/src/push.dart:61:36)
#7      Push.resend (package:realtime_client/src/push.dart:52:5)
#8      RealtimeChannel.rejoin (package:realtime_client/src/realtime_channel.dart:510:14)
#9      RealtimeChannel.rejoinUntilConnected (package:realtime_client/src/realtime_channel.dart:181:7)
#10     new RealtimeChannel.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:134:26)
#11     RetryTimer.scheduleTimeout.<anonymous closure> (package:realtime_client/src/retry_timer.dart:46:15)
#12     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#13     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#14     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#15     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

To Reproduce Steps to reproduce the behavior:

  1. Start Flutter desktop application
  2. get MacOS into sleep mode (e.g. by closing the MacBook)
  3. wake up after a while

Expected behavior I would expect the streams to reconnect and load all data that's changed while the system was suspended.

Version (please complete the following information): On macOS

│   ├── supabase_flutter...
├── supabase_flutter 1.10.11
│   ├── supabase 1.9.9
│   │   ├── functions_client 1.3.2
│   │   ├── gotrue 1.11.2
│   │   ├── postgrest 1.4.0
│   │   ├── realtime_client 1.1.3
│   │   ├── storage_client 1.5.1

I experienced an issue with all requests failing after system sleep due to invalid JWT, but this seems to be solved with the newest package version. Therefore my remaining problem could be related.

maxfornacon commented 1 year ago

I ended up implementing a workaround using the package flutter_desktop_sleep for now. It detects when the OS wakes up from sleep and then I reload the app entirely.

I'm not quite sure if this covers all cases where this issue occurs and it's kind off a bad user experience.

maxfornacon commented 1 year ago

I tried to reproduce the issues by creating a minimal flutter desktop project. You can find it in my repo: https://github.com/maxfornacon/supabase_test

To reproduce I ran it on MacOS and closed my MacBook (MacOS sleep). After waiting for >30min (often a couple of hours) the following errors occurred:

There is always this unhandled Exception:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:202:39)
#3      RealtimeChannel.onError.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:331:36)
#4      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#5      RealtimeClient._triggerChanError (package:realtime_client/src/realtime_client.dart:415:15)
#6      RealtimeClient._onConnClose (package:realtime_client/src/realtime_client.dart:396:7)
#7      RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:154:11)
#8      _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#9      _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#10     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#11     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#12     _ForwardingStream._handleDone (dart:async/stream_pipe.dart:99:10)
#13     _ForwardingStreamSubscription._handleDone (dart:async/stream_pipe.dart:161:13)
#14     _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#15     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#16     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#17     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#18     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:782:19)
#19     _StreamController._closeUnchecked (dart:async/stream_controller.dart:637:7)
#20     _StreamController.close (dart:async/stream_controller.dart:630:5)
#21     _RootZone.run (dart:async/zone.dart:1654:54)
#22     _FutureListener.handleWhenComplete (dart:async/future_impl.dart:190:18)
#23     Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:737:39)
#24     Future._propagateToListeners (dart:async/future_impl.dart:793:11)
#25     Future._completeWithValue (dart:async/future_impl.dart:567:5)
#26     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:640:7)
#27     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#28     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

This exception appears relatively quickly, but doesn't seem to break the streams on its own. But it might be helpful to qive a more detailed description what the exception means and why it occurs.

Some other exceptions that can occur: WebSocketChannelException

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: WebSocketChannelException: WebSocketChannelException: SocketException: Failed host lookup: '**.supabase.co' (OS Error: nodename nor servname provided, or not known, errno = 8)
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:202:39)
#3      RealtimeChannel.onError.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:331:36)
#4      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#5      RealtimeClient._triggerChanError (package:realtime_client/src/realtime_client.dart:415:15)
#6      RealtimeClient._onConnError (package:realtime_client/src/realtime_client.dart:407:5)
#7      _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)
#8      _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:360:15)
#9      _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:376:7)
#10     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
#11     _ForwardingStreamSubscription._addError (dart:async/stream_pipe.dart:128:11)
#12     _addErrorWithReplacement (dart:async/stream_pipe.dart:176:8)
#13     _HandleErrorStream._handleError (dart:async/stream_pipe.dart:274:11)
#14     _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:157:13)
#15     _RootZone.runBinaryGuarded (dart:async/zone.dart:1605:10)
#16     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:358:15)
#17     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:376:7)
#18     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
#19     _SyncStreamControllerDispatch._sendError (dart:async/stream_controller.dart:778:19)
#20     _StreamController._addError (dart:async/stream_controller.dart:656:7)
#21     _RootZone.runBinaryGuarded (dart:async/zone.dart:1605:10)
#22     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:358:15)
#23     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:376:7)
#24     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
#25     _SyncStreamControllerDispatch._sendError (dart:async/stream_controller.dart:778:19)
#26     _StreamController._addError (dart:async/stream_controller.dart:656:7)
#27     new Stream.fromFuture.<anonymous closure> (dart:async/stream.dart:251:18)
#28     _RootZone.runBinary (dart:async/zone.dart:1665:54)
#29     _FutureListener.handleError (dart:async/future_impl.dart:162:22)
#30     Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
#31     Future._propagateToListeners (dart:async/future_impl.dart:800:13)
#32     Future._completeError (dart:async/future_impl.dart:575:5)
#33     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:666:7)
#34     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#35     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

SocketException

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: SocketException: Failed host lookup: '***.supabase.co' (OS Error: nodename nor servname provided, or not known, errno = 8)
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:202:39)
#3      RealtimeChannel.onError.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:331:36)
#4      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#5      RealtimeClient._triggerChanError (package:realtime_client/src/realtime_client.dart:415:15)
#6      RealtimeClient._onConnError (package:realtime_client/src/realtime_client.dart:407:5)
#7      _RootZone.runUnary (dart:async/zone.dart:1660:54)
#8      _FutureListener.handleError (dart:async/future_impl.dart:165:22)
#9      Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
#10     Future._propagateToListeners (dart:async/future_impl.dart:800:13)
#11     Future._completeError (dart:async/future_impl.dart:575:5)
#12     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:666:7)
#13     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#14     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

heartbeat timeout

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: heartbeat timeout
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:202:39)
#3      RealtimeChannel.onError.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:331:36)
#4      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
#5      RealtimeClient._triggerChanError (package:realtime_client/src/realtime_client.dart:415:15)
#6      RealtimeClient._onConnClose (package:realtime_client/src/realtime_client.dart:396:7)
#7      RealtimeClient.connect.<anonymous closure> (package:realtime_client/src/realtime_client.dart:154:11)
#8      _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#9      _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#10     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#11     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#12     _ForwardingStream._handleDone (dart:async/stream_pipe.dart:99:10)
#13     _ForwardingStreamSubscription._handleDone (dart:async/stream_pipe.dart:161:13)
#14     _RootZone.runGuarded (dart:async/zone.dart:1581:10)
#15     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#16     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:7)
#17     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7)
#18     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:782:19)
#19     _StreamController._closeUnchecked (dart:async/stream_controller.dart:637:7)
#20     _StreamController.close (dart:async/stream_controller.dart:630:5)
#21     _RootZone.run (dart:async/zone.dart:1654:54)
#22     _FutureListener.handleWhenComplete (dart:async/future_impl.dart:190:18)
#23     Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:737:39)
#24     Future._propagateToListeners (dart:async/future_impl.dart:793:11)
#25     Future._completeWithValue (dart:async/future_impl.dart:567:5)
#26     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:640:7)
#27     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#28     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: "{:error, [message: \"Invalid token\", claim: \"exp\", claim_val: 1693849435]}"
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:277:19)
#3      Push._matchReceive.<anonymous closure> (package:realtime_client/src/push.dart:136:17)
#4      Iterable.forEach (dart:core/iterable.dart:325:35)
#5      Push._matchReceive (package:realtime_client/src/push.dart:135:48)
#6      Push.startTimeout.<anonymous closure> (package:realtime_client/src/push.dart:99:7)
#7      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)
...

Some of them are quite often in the logs and the stream doesn't receive any new events.

jstdk commented 1 year ago

I have a slightly different exception when opening a stream. Stream seems to work fine though, just this message

Error: 
    dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 941:28                get current
packages/supabase/src/supabase_stream_builder.dart 442:67                         [_addException]
packages/supabase/src/supabase_stream_builder.dart 348:9                          <fn>
packages/realtime_client/src/realtime_channel.dart 202:59                         <fn>
packages/realtime_client/src/realtime_channel.dart 331:36                         <fn>
packages/realtime_client/src/realtime_channel.dart 569:22                         trigger
packages/realtime_client/src/realtime_client.dart 415:14                          [_triggerChanError]
packages/realtime_client/src/realtime_client.dart 396:7                           [_onConnClose]
packages/realtime_client/src/realtime_client.dart 154:11                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
packages/stream_channel/src/guarantee_channel.dart 55:31                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
dart-sdk/lib/async/stream_controller.dart 883:29                                  close
packages/stream_channel/src/guarantee_channel.dart 188:38                         close
packages/web_socket_channel/html.dart 119:30                                      <fn>
dart-sdk/lib/async/zone.dart 1661:54                                              runUnary
dart-sdk/lib/async/future_impl.dart 156:18                                        handleValue
dart-sdk/lib/async/future_impl.dart 840:44                                        handleValueCallback
dart-sdk/lib/async/future_impl.dart 869:13                                        _propagateToListeners
dart-sdk/lib/async/future_impl.dart 632:7                                         [_complete]
dart-sdk/lib/async/stream_pipe.dart 61:11                                         _cancelAndValue
dart-sdk/lib/async/stream.dart 1581:7                                             <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 574:37  _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 579:39  dcall
dart-sdk/lib/html/dart2js/html_dart2js.dart 37263:58                              <fn>
dshukertjr commented 1 year ago

@maxfornacon Thanks for providing step by step of how to reproduce the issue. I was able to reproduce it, and the above PR should fix it! @jstdk Your issue should be fixed with the PR as well.

maxfornacon commented 1 year ago

@dshukertjr Does this mean the streams will reconnect automatically or do I need to handle it myself somehow?

dshukertjr commented 1 year ago

@maxfornacon It should reconnect automatically. I think it does reconnect automatically too, but it does throw an error before it reconnects. With the update though, no errors are thrown, and it will reconnect automatically.

jstdk commented 1 year ago

@dshukertjr, I updated Supabase but still see this in the log

image

Dart Debugger image

maxfornacon commented 1 year ago

@jstdk The PR is not yet merged.

jstdk commented 1 year ago

@maxfornacon, Thanks, I am so sorry. I saw RealTime updates in the Supabase latest version yesterday so I thought it was related.

dshukertjr commented 1 year ago

@maxfornacon @jstdk Sorry for taking some time to release a new version here, but the current most recent version should have this issue fixed!

maxfornacon commented 1 year ago

@dshukertjr I updated the package, relaunched the project and left the application running on my MacBook (closed) over night. Apparently I'm still getting the error Unhandled Exception: Bad state: Cannot add event after closing and the stream is not receiving any data changes.

I updated my test repo.

dshukertjr commented 1 year ago

@maxfornacon Okay, you reported three different errors, and it seems like the first one is at least not happening anymore. Not sure if the update mitigated the second error, but will look into the third error again.

maxfornacon commented 1 year ago

@dshukertjr In my first test, only the Bad state: ... error actually occurred. However, in my second test, the first error reappeared. What was different in the second test was that there was an interruption in the internet connection at some point. I'm not entirely sure if this is the cause yet, but it might be a relevant information.

So it seems the PR unfortunatley didn't fix it yet, but I appreciate your effort and work so far. :) Please let me know if there's anything else I can contribute to help find the cause.

maxfornacon commented 1 year ago

Okay, there is most definitely an issue with internet connectivity. I manually turned off wifi and after a couple of minutes I get the empty Unhandled Exception and also Unhandled Exception: SocketException: Failed host lookup: and Unhandled Exception: WebSocketChannelException: WebSocketChannelException: SocketException: Failed host lookup: The latter, however, are to be expected when there is no internet connection, I guess.

Interestingly the stream is still working after this as far as I can say for now.

jstdk commented 1 year ago

@maxfornacon , same error returned for me

jstdk commented 1 year ago

Feel that it is getting worse. I now gget page after page of these errors, even on pages where there is no stream active at all . It is now at a point where I can't read my own app log anymore, its only stream errors.


Error: 
    dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 941:28                get current
packages/supabase/src/supabase_stream_builder.dart 442:67                         [_addException]
packages/supabase/src/supabase_stream_builder.dart 348:9                          <fn>
packages/realtime_client/src/realtime_channel.dart 202:59                         <fn>
packages/realtime_client/src/realtime_channel.dart 331:36                         <fn>
packages/realtime_client/src/realtime_channel.dart 569:22                         trigger
packages/realtime_client/src/realtime_client.dart 415:14                          [_triggerChanError]
packages/realtime_client/src/realtime_client.dart 396:7                           [_onConnClose]
packages/realtime_client/src/realtime_client.dart 154:11                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
packages/stream_channel/src/guarantee_channel.dart 55:31                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
dart-sdk/lib/async/stream_controller.dart 883:29                                  close
packages/stream_channel/src/guarantee_channel.dart 188:38                         close
packages/web_socket_channel/html.dart 119:30                                      <fn>
dart-sdk/lib/async/zone.dart 1661:54                                              runUnary
dart-sdk/lib/async/future_impl.dart 156:18                                        handleValue
dart-sdk/lib/async/future_impl.dart 840:44                                        handleValueCallback
dart-sdk/lib/async/future_impl.dart 869:13                                        _propagateToListeners
dart-sdk/lib/async/future_impl.dart 632:7                                         [_complete]
dart-sdk/lib/async/stream_pipe.dart 61:11                                         _cancelAndValue
dart-sdk/lib/async/stream.dart 1581:7                                             <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 574:37  _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 579:39  dcall
dart-sdk/lib/html/dart2js/html_dart2js.dart 37263:58                              <fn>

dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 327:10  createErrorWithStack
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 337:28            _throw
dart-sdk/lib/core/errors.dart 120:5                                           throwWithStackTrace
dart-sdk/lib/async/zone.dart 1386:11                                          callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:15           <fn>
Error: 
    dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 941:28                get current
packages/supabase/src/supabase_stream_builder.dart 442:67                         [_addException]
packages/supabase/src/supabase_stream_builder.dart 348:9                          <fn>
packages/realtime_client/src/realtime_channel.dart 202:59                         <fn>
packages/realtime_client/src/realtime_channel.dart 331:36                         <fn>
packages/realtime_client/src/realtime_channel.dart 569:22                         trigger
packages/realtime_client/src/realtime_client.dart 415:14                          [_triggerChanError]
packages/realtime_client/src/realtime_client.dart 396:7                           [_onConnClose]
packages/realtime_client/src/realtime_client.dart 154:11                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
packages/stream_channel/src/guarantee_channel.dart 55:31                          <fn>
dart-sdk/lib/async/zone.dart 1582:10                                              runGuarded
dart-sdk/lib/async/stream_impl.dart 392:13                                        sendDone
dart-sdk/lib/async/stream_impl.dart 402:7                                         [_sendDone]
dart-sdk/lib/async/stream_impl.dart 291:7                                         [_close]
dart-sdk/lib/async/stream_controller.dart 792:19                                  [_sendDone]
dart-sdk/lib/async/stream_controller.dart 817:7                                   [_sendDone]
dart-sdk/lib/async/stream_controller.dart 647:7                                   [_closeUnchecked]
dart-sdk/lib/async/stream_controller.dart 640:5                                   close
dart-sdk/lib/async/stream_controller.dart 883:29                                  close
packages/stream_channel/src/guarantee_channel.dart 188:38                         close
packages/web_socket_channel/html.dart 119:30                                      <fn>
dart-sdk/lib/async/zone.dart 1661:54                                              runUnary
dart-sdk/lib/async/future_impl.dart 156:18                                        handleValue
dart-sdk/lib/async/future_impl.dart 840:44                                        handleValueCallback
dart-sdk/lib/async/future_impl.dart 869:13                                        _propagateToListeners
dart-sdk/lib/async/future_impl.dart 632:7                                         [_complete]
dart-sdk/lib/async/stream_pipe.dart 61:11                                         _cancelAndValue
dart-sdk/lib/async/stream.dart 1581:7                                             <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 574:37  _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 579:39  dcall
dart-sdk/lib/html/dart2js/html_dart2js.dart 37263:58                              <fn>

dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 327:10  createErrorWithStack
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 337:28            _throw
dart-sdk/lib/core/errors.dart 120:5                                           throwWithStackTrace
dart-sdk/lib/async/zone.dart 1386:11                                          callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:15           <fn>
maxfornacon commented 1 year ago

@maxfornacon @jstdk Sorry for taking some time to release a new version here, but the current most recent version should have this issue fixed!

I noticed that in the release @dshukertjr mentioned here (1.10.16) there wasn't a realtime_client update (it was still 1.2.1 which was released almost a month ago) But today they released supabase_flutter 1.10.18 and it came with realtime_client 1.2.2. I might be wrong but maybe the fix wasn't published until today somehow.

So I made another test with my test project and didn't receive errors except for the WebSocketExceptions. But that's probably due to loss of internet connection (and therefore to be expected I guess)

But still the streams were not reconnecting and that's what I care most about.

jstdk commented 1 year ago

@maxfornacon. Think you are right, I just updated to 1.10.18 and the errors are gone. Thanks

maxfornacon commented 1 year ago

@dshukertjr I found steps to reliably reproduce the disconnected streams.

  1. Set the JWT expiry limit to something small (like 60 seconds) to reduce testing time
  2. Start application
  3. Either set OS into sleep mode or turn off wifi (could be separate issues)
  4. Wait a couple of minutes so that the JWT is refreshed (a couple of times)
  5. wake up or reconnect wifi

After that the stream should not refresh when data in database changes.

dshukertjr commented 1 year ago

I was receiving a lot of SocketException and WebSocketException even on the latest version of supabase_flutter actually, but this PR should finally fix that. https://github.com/supabase/supabase-flutter/pull/637

Thanks for the steps to reproduce the stream not reconnecting issue. I was able to reproduce it on my end. Let me see what I can do.

ymerdrengene commented 1 year ago

Hi @dshukertjr, do you know when the update will be available? :) I also receive a lot of WebSocketChannelException

dshukertjr commented 1 year ago

@ymerdrengene We publish weekly updates on every Monday usually!

maxfornacon commented 11 months ago

@dshukertjr I can confirm that I'm not receiving above mentioned exceptions anymore in 1.10.19.

But after simulating a disconnected wifi and turning it on again. I get the following.

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: "{:error, [message: \"Invalid token\", claim: \"exp\", claim_val: 1695818483]}"
#0      SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67)
#1      SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9)
#2      RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:277:19)
#3      Push._matchReceive.<anonymous closure> (package:realtime_client/src/push.dart:136:17)
#4      Iterable.forEach (dart:core/iterable.dart:347:35)
#5      Push._matchReceive (package:realtime_client/src/push.dart:135:48)
#6      Push.startTimeout.<anonymous closure> (package:realtime_client/src/push.dart:99:7)
#7      RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:569:22)

and this one multiple times:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: StreamSink is closed
#0      _StreamSinkImpl.add (dart:_http/http_impl.dart:914:7)
#1      _WebSocketImpl.add (dart:_http/websocket_impl.dart:1222:11)
#2      DelegatingStreamSink.add (package:async/src/delegate/stream_sink.dart:35:11)
#3      _CompleterSink.add (package:web_socket_channel/src/sink_completer.dart:88:25)
#4      RealtimeClient.push.callback.<anonymous closure> (package:realtime_client/src/realtime_client.dart:294:55)
#5      new RealtimeClient.<anonymous closure> (package:realtime_client/src/realtime_client.dart:134:21)
#6      RealtimeClient.push.callback (package:realtime_client/src/realtime_client.dart:294:13)
#7      RealtimeClient.push (package:realtime_client/src/realtime_client.dart:311:9)
#8      Push.send (package:realtime_client/src/push.dart:61:36)
#9      Push.resend (package:realtime_client/src/push.dart:52:5)
#10     RealtimeChannel.rejoin (package:realtime_client/src/realtime_channel.dart:510:14)
#11     RealtimeChannel.rejoinUntilConnected (package:realtime_client/src/realtime_channel.dart:181:7)
#12     new RealtimeChannel.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:134:26)
#13     RetryTimer.scheduleTimeout.<anonymous closure> (package:realtime_client/src/retry_timer.dart:46:15)
#14     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#15     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#16     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#17     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
dshukertjr commented 11 months ago

Yup, the invalid token issue does happen when the token expires between the time of going into offline and coming back. We are in the process of fixing this one as well.

maxfornacon commented 11 months ago

@dshukertjr Can you provide us with an update regarding the reconnecting issue?

formalpair commented 10 months ago

Hello Guys,

I'm facing related issues here. Sometimes my chat just stop to work with the following errors:

I/flutter (24103): Exception: "{:error, [message: \"Invalid token\", claim: \"exp\", claim_val: 1700706731]}" I/flutter (24103): #0 SupabaseStreamBuilder._addException (package:supabase/src/supabase_stream_builder.dart:442:67) I/flutter (24103): #1 SupabaseStreamBuilder._getStreamData.<anonymous closure> (package:supabase/src/supabase_stream_builder.dart:348:9) I/flutter (24103): #2 RealtimeChannel.subscribe.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:288:19) I/flutter (24103): #3 Push._matchReceive.<anonymous closure> (package:realtime_client/src/push.dart:136:17) I/flutter (24103): #4 Iterable.forEach (dart:core/iterable.dart:347:35) I/flutter (24103): #5 Push._matchReceive (package:realtime_client/src/push.dart:135:48) I/flutter (24103): #6 Push.startTimeout.<anonymous closure> (package:realtime_client/src/push.dart:99:7) I/flutter (24103): #7 RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:622:22) I/flutter (24103): #8 new RealtimeChannel.<anonymous closure> (package:realtime_client/src/realtime_channel.dart:179:7) I/flutter (24103): #9 RealtimeChannel.trigger (package:realtime_client/src/realtime_channel.dart:622:22) I/flutter (24103): #10 RealtimeClient.onConnMessage.<anonymous closure>.<anonymous closure> (

Do we have any update for this?

dshukertjr commented 10 months ago

Thanks for following up with this one, and sorry that it's taking so long for this to be resolved. We are investigating this issue, but not going to lie it has been tough trying to pin point the root cause. We do understand that this is a critical issue for Supabase users, and will keep digging into the cause of it.

maxfornacon commented 8 months ago

If there is any information regarding the error that you can share with us, I would be very grateful. Perhaps the community can also contribute to finding a solution or has an idea that leads to a solution. This error is very relevant for our business, as we rely on a reliable real-time connection.