Error debugging Flutter in Visual Studio Code - flutter

When debugging an async function, when there is a line with await, it can't debug the next line and I never get to know the response body. If I make a break point either. And this is happening to me in all lines with await.
#override
Future getCountries() async {
try {
final response = await httpCache(
'$domain/wp-json/api/flutter_user/get_countries'.toUri()!);
var body = convert.jsonDecode(response.body);
return body;
} catch (err) {
rethrow;
}
}
Know if there is any configuration to debug asynchronous functions in Flutter with VSCode.

Related

How do I put common logic to every Future functions?

I have over 200 Future functions request rest api.
ex)
Future fetchSomething(jsonData) async {
var dio = Dio();
try {
var response = await dio.post(
"serverurl",
data: FormData.fromMap(jsonData),
options:Options(contentType: Headers.formUrlEncodedContentType));
return response.data;
}
catch (e) {
throw Exception(e);
}
}
and I want the app pop modal that explain what error it is when the error occur
since I have over 200 Future functions, It's going to be hassle to put exception logic to every Future function.
Is there a way to put common logic easily?
Thank you.

Function expressions can't be named: then(

Im having issues with my code and since I'm new at using Flutter, I have no clue on how to fix it. I was trying to fix the http.get(string) and I kind of did, but now I'm having issues with then(()).
void submitForm(FeedbackForm feedbackForm) async {
try {
await http.get(Uri.parse(URL + feedbackForm.toParams()).then((response)) {
callback(convert.jsonDecode(response.body['status']));
});
} catch (e) {
print(e);
}
}
}
It seems you got a parenthesis missplaced:
await http.get(...).then((response) => callback(...))
The them allows you to use the result of the previous Future, as soon as it becomes available. If you find it confusing you can declare one variable at a time.
final response = await http.get(...);
// Check if response was as expected
await callback();

How to catch cloud functions onCall functions.https.HttpsError by Flutter with cloud_functions package

I'm using Flutter cloud_functions package and Cloud functions. I want to catch functions.https.HttpsError by on CloudFunctionsException (Client side) I can't catch functions.https.HttpsError with Flutter no matter what I intentionally throw.
Is it impossible to catch functions.https.HttpsError throw by cloud functions package with CloudFunctionsException?
Help me.
cloud functions
export const sampleFunctions = functions.region(REGION).https.onCall((data, context) => {
if (!data.hoge) throw new functions.https.HttpsError('failed-precondition', 'some reason');
return { response: data.fuga };
});
dart
Future<dynamic> sampleFunction() async {
final _cloudFunctions = CloudFunctions(region: 'asia-northeast1');
final _sampleFunctions = _cloudFunctions.getHttpsCallable(
functionName: 'sampleFunctions',
);
try {
final resp = await _sampleFunctions.call(<String, dynamic>{
'fuga': 'fuga',
});
print(resp);
} on CloudFunctionsException catch (e) {
print(e.code);
print(e.message);
}
}
There is a call function implementation in Dart docs. If you take a look on it CloudFunctionsException is thrown only when exception property code == 'functionsError'.
With functions.https.HttpsError you are code from the first parameter( 'failed-precondition' in the example). Unfortunately HttpError has limited possible values of error codes and "functionsError" is not in the list.
So it seems that it will not work this way.
I hope it will help!

Dart Completer.complete() results never resolve

I have a function that returns a future which depends on the result of a callback to resolve:
Future connectSocket(String email, String password, {Function onConnectCallback}) async {
var completer = new Completer();
print("Connecting...");
var query = getQueryString(email, password);
socketIO = await SocketIOManager().createInstance(SocketOptions(localDomainWindows, query: query));
socketIO.on("loginError", (data) {
print("Login err");
_connected = false;
connectedCallback();
completer.complete(false);
});
socketIO.onConnect((data) {
print("***CONNECTED***");
_connected = true;
completer.complete(true);
connectedCallback();
});
socketIO.connect();
return completer.future;
}
I can see ***CONNECTED*** printed to the console, and my socket server acknowledges the connection, but the function await-ing the resolution never resumes, it just hangs.
socketConnection.connectSocket(_email, _password)
.then((success) {
print("SUCCESS") // never gets printed
}
The only possible explanation for this is that some code in the callback is blocking your program from continuing because Completer.complete should otherwise always make the future complete.
If it is blocked, however, the event loop will never be able to call your code.
As a bool assignment should never be blocking (_connected = true;), the only part of your function that could be halting your program is connectedCallack();. If you remove or fix it, you should see your future complete.

Retry Http Get request if there is no response in Flutter

getData() async {
http.Response response = await http.get('https://www.example.com/);
print(response.body);
}
The above function works to get the HTML code of a page but it fails in some cases. The function is sometimes never completed and it waits forever to get response( For example, if the app is opened while internet is off and even when its turned on, it never connects). In such situations is there any way to retry ?
I tried the http retry package but it gives me 15+ errors.
Example code for how this could be done:
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List> loadData() async {
bool loadRemoteDatatSucceed = false;
var data;
try {
http.Response response = await http.post("https://www.example.com",
body: <String, String>{"username": "test"});
data = json.decode(response.body);
if (data.containsKey("success")) {
loadRemoteDatatSucceed = true;
}
} catch (e) {
if (loadRemoteDatatSucceed == false) retryFuture(loadData, 2000);
}
return data;
}
retryFuture(future, delay) {
Future.delayed(Duration(milliseconds: delay), () {
future();
});
}
You can use RetryPolicy from http package to retry your connection, just create your own class and inherit form RetryPolicy and override these function like the following example, then create a Client using HttpClientWithInterceptor.build and add your custom retryPolicy as a parameter, this will retry your request for a number of times until a condition is met, if not, it'll just stop retrying.
import 'package:http/http.dart';
class MyRetryPolicy extends RetryPolicy {
final url = 'https://www.example.com/';
#override
// how many times you want to retry your request.
int maxRetryAttempts = 5;
#override
Future<bool> shouldAttemptRetryOnResponse(ResponseData response) async {
//You can check if you got your response after certain timeout,
//or if you want to retry your request based on the status code,
//usually this is used for refreshing your expired token but you can check for what ever you want
//your should write a condition here so it won't execute this code on every request
//for example if(response == null)
// a very basic solution is that you can check
// for internet connection, for example
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
return true;
}
return false;
} on SocketException catch (_) {
return false;
}
}
}
then create and use a client to make your requests.
it will automatically retry the request if the condition you wrote is met.
Client client = HttpClientWithInterceptor.build(
retryPolicy: ExpiredTokenRetryPolicy(),
);
final response = await client.get('https://www.example.com/);
there is also a package to check for internet connection if that your problem, see connectivity
You can use try-catch blocks inside async functions like you would in synchronous code. Perhaps you'd be able to add some sort of error handling mechanism in the function, and retry the function on error? Here's some documentation on that one.
Example from the docs:
try {
var order = await getUserOrder();
print('Awaiting user order...');
} catch (err) {
print('Caught error: $err');
}
You can also catch specific Exceptions, per this github issue.
doLogin(String username, String password) async {
try {
var user = await api.login(username, password);
_view.onLoginSuccess(user);
} on Exception catch(error) {
_view.onLoginError(error.toString());
}
}
EDIT: This may also help.
While we're at it, look here for a function that reattempts an async operation however many times you need.