Closed putraxor closed 4 years ago
Thanks for reporting @putraxor . I am not 100% sure what had gone wrong, it looks to me you host machine went offline after a few hours.
I think this should not be closed. I'm getting this error too and i'm using teledart in an intranet application.
This error in fact happens if server looses internet connection. But i think crashing the whole app just because the server lost connectivity is not the best approach. What happens if the server running an app that uses teledart looses internet connection because of a carrier outage but the app is used inside the company's network (not on the internet!)? Is there anything i can do to prevent the whole app crash (maybe some error handling)?
Thanks in advance!
@ja2375 i understand that crashing the application might not be the best, however due to long poll is basically making get request to the server in a interval, the best we can do is to swallow the error and keep retrying but then developer might miss errors cause by servier configuration. It is recommanded to use webhooks instead of long poll, as it is a passive approch rather than making get requests actively.
I'm testing to handle the exception by running all the application inside a runZonedGuarded()
, which allows to handle all unhandled exceptions and preventing the app from crashing.
For the time being, i did not get any LongPollingException
. I will keep testing because i want to know what happens if i catch the LongPollingException
in the runZonedGuarded
's onError
.
Yesterday i got a LongPollingException
at some point. But i checked and the application not only did not crash but also it was just working fine (including the telegram bot) when the machine recovered from the internet outage.
So i'm guessing that this is the correct way (and also the only one i found) that allows handling this exception.
Here is exactly how you can handle it, but in fact there is no need to do anything when a LongPollingException
is thrown as teledart will continue to work fine.
void main() =>
runZonedGuarded<void>(() {
// Your main function here
}, (e, s) {
switch(e.runtimeType) {
case TeleDartException:
if(e.toString().contains('LongPollingException')) {
/// You can handle here the LPE...
/// But it is not really needed as teledart
/// handles it by itself and keeps working
/// despite of throwing LPE.
}
}
print('An error occurred: $e');
});
/// You can handle here the LPE... /// But it is not really needed as teledart /// handles it by itself and keeps working /// despite of throwing LPE.
I am looking at the longPooling code and seems that when an error occurs, the long pooling stops it's recursive call, take a look:
/// Private long polling loop, throws [LongPollingException] on error.
void _recursivePolling() {
if (_isPolling) {
telegram
.getUpdates(
offset: offset,
limit: limit,
timeout: timeout,
allowed_updates: allowed_updates)
.then((updates) {
if (updates.isNotEmpty) {
for (var update in updates) {
emitUpdate(update);
offset = update.update_id + 1;
}
}
_recursivePolling();
}).catchError((error) =>
// TODO: find out what exceptions can be ignored
error is io.HandshakeException
? _recursivePolling()
: throw LongPollingException(error.toString())); //The recursive call stops here
}
}
Maybe I am wrong, can you confirm that? Those Unhandled erros are driving me crazy too =/
seems
@shinayser Yes, you are correct. Currently it only ignore io.HandshakeException
. I am interested to know what execreption you are getting.
@ja2375 the code snippet you post bascally is jsut ignoring all TeleDartExceptions, which I am not too sure if it is a good idea.
I am looking into enhancing the long poll method right now, my idea is to halt when receiving client errors (e.g. 401 unauthorised), keep in the _recursivePolling
loop otherwise and perhaps log the error somewhere, most likely just a console log.
@shinayser @ja2375 give #118 a try, and let me know if what you think
Hey @DinoLeung I will test it when I get home! My error case is really simple to replicate if you want to try: just start the long pooling bot, then cut off internet connection. It will crash.
@DinoLeung I'm getting the following exception after upgrading to 0.0.49, and i think it can be related to this issue. 3 seconds after starting the app, it throws:
Invalid argument (onError): Error handler must accept one Object or one Object and a StackTrace as arguments, and return a a valid result: Closure: (HttpClientException) => void from Function '_onRecursivePollingHttpError@196175636':.
#0 _registerErrorHandler (dart:async/future_impl.dart:828:3)
#1 Future.catchError (dart:async/future_impl.dart:308:17)
#2 LongPolling._recursivePolling (package:teledart/src/teledart/fetch/long_polling.dart:98:12)
#3 LongPolling._recursivePolling.<anonymous closure> (package:teledart/src/teledart/fetch/long_polling.dart:96:13)
#4 _rootRunUnary (dart:async/zone.dart:1198:47)
#5 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#6 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#7 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#8 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#9 Future._completeWithValue (dart:async/future_impl.dart:529:5)
#10 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
#11 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
#12 Telegram.getUpdates (package:teledart/src/telegram/telegram.dart)
#13 _rootRunUnary (dart:async/zone.dart:1198:47)
#14 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#15 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#16 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#17 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#18 Future._completeWithValue (dart:async/future_impl.dart:529:5)
#19 Future.timeout.<anonymous closure> (dart:async/future_impl.dart:797:16)
#20 _rootRunUnary (dart:async/zone.dart:1198:47)
#21 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#22 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#23 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#24 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#25 Future._completeWithValue (dart:async/future_impl.dart:529:5)
#26 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
#27 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
#28 _withClient (package:http/http.dart)
#29 _rootRunUnary (dart:async/zone.dart:1198:47)
#30 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#31 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#32 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#33 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#34 Future._completeWithValue (dart:async/future_impl.dart:529:5)
#35 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15)
#36 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13)
#37 Response.fromStream (package:http/src/response.dart)
#38 _rootRunUnary (dart:async/zone.dart:1198:47)
#39 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#40 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#41 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#42 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#43 Future._completeWithValue (dart:async/future_impl.dart:529:5)
#44 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
#45 _rootRun (dart:async/zone.dart:1190:13)
#46 _CustomZone.run (dart:async/zone.dart:1093:19)
#47 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#48 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
#49 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#50 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#51 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
#52 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:404:11)
#53 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
#54 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
I didn't get this exception on 0.0.47, so it should be a recent addition.
@ja2375 whoops, just fixed this. An update will be up soonish
Describe the bug
Unhandled exception after a few hours
LongPollingException: HttpClientException: SocketException: Failed host lookup: 'api.telegram.org' (OS Error: nodename nor servname provided, or not known, errno = 8)
Logs