Why doesn't my method work in DioError catch in Flutter/Dart? - flutter

I am making a request to my database like this:
//Airtable (find a record)
void airtableFind() async {
try {
final response = await Dio().get(
'https://api.airtable.com/v0/'+projectBase+'/'+recordName,
queryParameters: {
'filterByFormula': 'SEARCH('+'"'+username+'"'+',{Name})' // Searches the value 'Cactus' in the {'Short description'} field.
},
options: Options(
contentType: 'Application/json',
headers: {
'Authorization': 'Bearer'+' '+apiKey,
'Accept': 'Application/json',
},
),
);
// TODO: Whatever you want to do with the response. A good practice is to transform it into models and than work with them
// print(response);
// print(response.data['records'][0]['id']);
idString = response.data['records'][0]['id'];
// if (idString.isNotEmpty) (
// showInvalidUsernameDialog(context)
// // TODO: Need to inform about success
// );
} on DioError catch (e) {
// TODO: Error handling
if (e.response != null) {
// print(e.response.data);
print(e);
showInvalidUsernameDialog(context);
} else {
// print(e.request);
print(e.message);
showInvalidUsernameDialog(context);
}
}
}
If my user enters the correct word (username), then everything works correctly. But there is always a risk that a person is mistaken. And I want to indicate this with the showInvalidUsernameDialog(context); dialog box, but for some reason it does not pop up.
I see errors in the console:
I/flutter(4484): DioError [DioErrorType.response]: Http status error [422]
I/flutter ( 4484): Source stack:
I/flutter(4484): #0 DioMixin.fetch(package:dio/src/dio_mixin.dart:488:35)
I/flutter ( 4484): #1 DioMixin.request (package:dio/src/dio_mixin.dart:483:12)
I/flutter ( 4484): #2 DioMixin.patch (package:dio/src/dio_mixin.dart:249:12)
I/flutter(4484): #3 _RouteState.airtableUpdate(package:example/main.dart:1498:36)
I/flutter ( 4484): #4 _RouteState.build.<anonymous closure> (package:example/main.dart:1617:13)
I/flutter ( 4484): #5 _RouteState.build.<anonymous closure> (package:example/main.dart:1612:24)
I/flutter(4484): #6 EditableTextState._finalizeEditing (package:flutter/src/widgets/editable_text.dart:2148:18)
I/flutter(4484): #7 EditableTextState.performAction(package:flutter/src/widgets/editable_text.dart:1999:9)
I/flutter(4484): #8 TextInput._handleTextInputInvocation(package:flutter/src/services/text_input.dart:1746:37)
I/flutter ( 4484): #9 MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:404:55)
I/flutter ( 4484): #10 MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_chan
E/flutter ( 4484): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0
E/flutter ( 4484): #0 List.[] (dart:core-patch/growable_array.dart:264:36)
E/flutter ( 4484): #1 _RouteState.airtableFind (package:example/main.dart:1473:42)
E/flutter ( 4484): <asynchronous suspension>
E/flutter ( 4484):
And that's to be expected, since I'm deliberately entering the wrong username. But I want to get not only a list of errors in the console, but also a dialog box. Why doesn't it appear?
The dialog box call method is correct. I put it in the part of the code that fires when the username is valid. It appears exactly as intended.
But why doesn't this method work in this part of the code?
on DioError catch (e) {
// TODO: Error handling
if (e.response != null) {
// print(e.response.data);
print(e);
showInvalidUsernameDialog(context);
} else {
// print(e.request);
print(e.message);
showInvalidUsernameDialog(context);
}
And how can I make this dialog appear in case of an error?
Edit 1. _RouteState.airtableFind (package:example/main.dart:1473:42) is referring to idString = response.data['records'][0]['id'];. This happens when my user enters their login incorrectly.

Use catch directly and check if its of type DioError. This is a known behaviour.. Its not catching 400 or 500 errors
https://github.com/flutterchina/dio/issues/1198
try{
}catch(e){
print(e.toString());
}
or
try{
}catch(e){
if(e is DioError)
{
}
}

Related

Flutter Bluetooth Null Check Exception although null was checked

Here is the main() function. Here is the initializisation of the "flutter_isolate" library
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
...
class BTConnection {
BluetoothConnection? c;
Future<void> connect(address) async {
print('Connecting to the device ...');
BluetoothConnection connection =
await BluetoothConnection.toAddress(address);
c = connection;
print('Connected to the device');
FlutterIsolate.spawn(listenToData, connection);
}
Future<void> disconnect() async {
if (c != null) {
await c?.finish();
print("disconnected from device");
} else {
print("There is no bluetooth connection to disconnect");
}
}
#pragma('vm:entry-point')
Future<void> listenToData(connection) async {
print("listening ...");
await connection.input?.listen((Uint8List data) {
print('Data incoming: ${ascii.decode(data)}');
connection.output.add(data); // Sending data
}).onDone(() {
print('Disconnected by remote request');
});
}
}
Whenever I run the code and enter the correct MAC address in the text field, the function connect() is called and after a few seconds the message "Connected to the device" is printed. The following error message is then output:
E/flutter (26066): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
E/flutter (26066): #0 FlutterIsolate.spawn
flutter_isolate.dart:28
E/flutter (26066): #1 BTConnection.connect
main.dart:110
E/flutter (26066): <asynchronous suspension>
E/flutter (26066): #2 _HomePageState.build.<anonymous closure>
main.dart:70
E/flutter (26066): <asynchronous suspension>
E/flutter (26066):

Trying to upload image using DIO. (error)

Hello i hope you all good. Im trying to upload an image but im stuck and getting some errors.
I/flutter (23022): El error es: DioError [DioErrorType.other]: Converting object to an encodable object failed: FormData
I/flutter (23022): #0 _JsonStringifier.writeObject (dart:convert/json.dart:794:7)
I/flutter (23022): #1 _JsonStringStringifier.printOn (dart:convert/json.dart:983:17)
I/flutter (23022): #2 _JsonStringStringifier.stringify (dart:convert/json.dart:968:5)
I/flutter (23022): #3 JsonEncoder.convert (dart:convert/json.dart:345:30)
I/flutter (23022): #4 JsonCodec.encode (dart:convert/json.dart:231:45)
I/flutter (23022): #5 DefaultTransformer.transformRequest (package:dio/src/transformer.dart:77:21)
I/flutter (23022): #6 DioMixin._transformData (package:dio/src/dio_mixin.dart:735:39)
I/flutter (23022): #7 DioMixin._dispatchRequest (package:dio/src/dio_mixin.dart:656:26)
I/flutter (23022): #8 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:605:7)
I/flutter (23022): #9 DioMixin.fetch._requestInterceptorWrapper.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:dio/src/dio_mixin.dart:517:28)
I/flutter (23022): #10 DioMixin.checkIfNeedEnqueue (package:dio/src/dio_mixin.dart:789:22)
I/flutter (23022): #11 DioMixin.fetch._requestInterceptorWrapper.<ano
This is my file:
https://github.com/bRUNS123/hydra
I hope someone can help me!
This is my function to upload:
void _uploadFile(filePath) async {
try {
String filename = p.basename(filePath!.path.split('/').last);
dio.FormData.fromMap({
'files': {
await dio.MultipartFile.fromFile(
filePath.path,
filename: filename,
contentType: MediaType(
'image',
'jpeg',
),
),
},
'app_label': 'files',
'app_model': 'file',
});
await Dio()
.post('http://10.0.2.2:8000/objects/', data: FormData)
.then((value) {
// if (value.toString() == '1') {
// print('La foto se ha subido correctamente');
// } else {
// print('Hubo un error');
// }
});
} catch (e) {
print('El error es: $e');
}
}
Thanks for reading and i hope someone can help me!
have a nice day!
PS: i already check my server with postman.
Use MultipartRequest class from http package instead (easiest way).
try {
MultipartRequest request = MultipartRequest(
'POST',
Uri.parse("http://10.0.2.2:8000/objects/"),
);
request.files.add(
MultipartFile.fromBytes(
'files',
(await File(filePath).readAsBytes()),
filename: p.basename(filePath.split('/').last);,
),
);
request.fields.addAll(
{
'app_label': 'files',
'app_model': 'file',
},
);
// Parse JSON Response from server {"success" : true, "message" : "..."}
var json = jsonDecode(
String.fromCharCodes(
await (await request.send()).stream.toBytes(),
),
);
} catch (e) {
debugPrint(e.toString());
}

Unhandled Exception: This widget has been unmounted, in flutter?

I am trying to submit data to the API but throwing a error that the widget is unmounted.
Here is the code:
SubmitRequest() async {
var newValue;
if(selectedIndex == 0){
newValue = 2;
}else if(selectedIndex == 1){
newValue = 3;
}else{
newValue = null;
}
var remark;
if(selectedIndex == 0){
remark = "Wrong";
}else if(selectedIndex == 1){
remark = "Invalid";
}else{
return null;
}
var url = Uri.parse(url);
var header = {
"API-Key": "eeee",
"Content-Type": "application/json",
};
final bdy = jsonEncode({
"action" :"dhdhd",
"token":"df23311",
"date": getCurrentDate().toString(),
});
var jsonresponse = await http.post(url, headers: header, body: bdy);
print(jsonresponse.statusCode);
if (jsonresponse.statusCode == 200) {
Utils.showToastSuccess("Submitted Successfully").show(context);
print("submit success");
}else{
Utils.showToastError("Submit Failed, Try Again").show(context);
}
}
when I try to run this the toast will not popup and throws an error:
E/flutter ( 615): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
E/flutter ( 615): Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.
E/flutter ( 615): #0 State.context.<anonymous closure> (package:flutter/src/widgets/framework.dart:909:9)
E/flutter ( 615): #1 State.context (package:flutter/src/widgets/framework.dart:915:6)
E/flutter ( 615): #2 _WrongOrInvalidState.SubmitRequest (package:bmteacher/ui/History/invalid.dart:76:63)
E/flutter ( 615): <asynchronous suspension>
E/flutter ( 615):
When you call the method submitRequest(), are you using the keyword await? Because it the method you are trying to use a context that has already been disposed, so probably you app is not waiting the method submitRequest() to finish.

How to log out user and How to check user verify mail

I got the following problem.
When user register he will be on a page, where I show a message like check your Email account. And when user check his account and confirm his mail he automatically get to homepage. So far so good. But when user press register button an get mail and reload the page he get also inside homepage without confirm his mail.
I trie this
Future<String> signIN(String email, String password) async {
try {
UserCredential result =await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email.trim(),
password: password,
);
User user = result.user;
if(user.emailVerified){
return user.uid;
}
} on FirebaseAuthException catch (e) {
but not working.
here's my verify email page
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:projectandroidstudiodenya/seitenleiste/homepage.dart';
class VerifyScreen extends StatefulWidget {
#override
_VerifyScreenState createState() => _VerifyScreenState();
}
class _VerifyScreenState extends State<VerifyScreen> {
final auth= FirebaseAuth.instance;
User user;
Timer timer;
#override
void initState() {
user= auth.currentUser;
user.sendEmailVerification();
timer= Timer.periodic(Duration(seconds: 5), (timer) {
checkEmailverifyed();
});
super.initState();
}
#override
void dispose() {
timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:Center(
)
);
}
Future<void> checkEmailverifyed() async{
user=auth.currentUser;
await user.reload();
if(user.emailVerified){
timer.cancel();
Navigator.of(context).
pushReplacement(MaterialPageRoute(builder:(context)=> Homepage()));
}
}
}
Maybe anyone can help.
And also when user press logout button nothing happened. but when user restart the app he logged out.
here's my logout pressed method:
onPressed: () {
FirebaseAuth.instance.signOut();
FirebaseAuth.instance.signOut();Navigator.pushNamedAndRemoveUntil(context, LoginScreen.route, (route) => false);
Heres the error of the sign out:
D/FirebaseAuth(26776): Notifying id token listeners about a sign-out event.
D/FirebaseAuth(26776): Notifying auth state listeners about a sign-out event.
E/flutter (26776): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Could not find a generator for route RouteSettings("SignIn", null) in the _WidgetsAppState.
E/flutter (26776): Make sure your root app widget has provided a way to generate
E/flutter (26776): this route.
E/flutter (26776): Generators for routes are searched for in the following order:
E/flutter (26776): 1. For the "/" route, the "home" property, if non-null, is used.
E/flutter (26776): 2. Otherwise, the "routes" table is used, if it has an entry for the route.
E/flutter (26776): 3. Otherwise, onGenerateRoute is called. It should return a non-null value for any valid route not handled by "home" and "routes".
E/flutter (26776): 4. Finally if all else fails onUnknownRoute is called.
E/flutter (26776): Unfortunately, onUnknownRoute was not set.
E/flutter (26776): #0 _WidgetsAppState._onUnknownRoute.<anonymous closure> (package:flutter/src/widgets/app.dart:1219:9)
E/flutter (26776): #1 _WidgetsAppState._onUnknownRoute (package:flutter/src/widgets/app.dart:1234:6)
E/flutter (26776): #2 NavigatorState._routeNamed (package:flutter/src/widgets/navigator.dart:4148:37)
E/flutter (26776): #3 NavigatorState.pushNamedAndRemoveUntil (package:flutter/src/widgets/navigator.dart:4391:34)
E/flutter (26776): #4 Navigator.pushNamedAndRemoveUntil (package:flutter/src/widgets/navigator.dart:2042:34)
E/flutter (26776): #5 _openSignOutDrawer.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:projectandroidstudiodenya/seitenleiste/seitenleiste.dart:188:90)
E/flutter (26776): #6 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (26776): #7 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (26776): <asynchronous suspension>
E/flutter (26776):
And the error of the sig in:
E/flutter (26776): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The getter 'emailVerified' was called on null.
E/flutter (26776): Receiver: null
E/flutter (26776): Tried calling: emailVerified
E/flutter (26776): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter (26776): #1 AuthService.signIN (package:projectandroidstudiodenya/services/auth.dart:44:44)
E/flutter (26776): #2 _LoginScreenState._buildLoginBtn.<anonymous closure> (package:projectandroidstudiodenya/authenticate/signin.dart:170:48)
E/flutter (26776): #3 _LoginScreenState._buildLoginBtn.<anonymous closure> (package:projectandroidstudiodenya/authenticate/signin.dart:168:24)
E/flutter (26776): #4 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:994:20)
E/flutter (26776): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (26776): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:607:11)
E/flutter (26776): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
E/flutter (26776): #8 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:267:7)
E/flutter (26776): #9 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
E/flutter (26776): #10 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:443:20)
E/flutter (26776): #11 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:419:22)
E/flutter (26776): #12 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:288:11)
E/flutter (26776): #13 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:374:7)
E/flutter (26776): #14 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:338:5)
E/flutter (26776): #15 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:296:7)
E/flutter (26776): #16 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:279:7)
E/flutter (26776): #17 _rootRunUnary (dart:async/zone.dart:1370:13)
E/flutter (26776): #18 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (26776): #19 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1170:7)
E/flutter (26776): #20 _invoke1 (dart:ui/hooks.dart:186:10)
E/flutter (26776): #21 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:282:7)
E/flutter (26776): #22 _dispatchPointerDataPacket (dart:ui/hooks.dart:96:31)
E/flutter (26776):
My sig in method looks like that:
Future<String> signIN(String email, String password) async {
try {
if(FirebaseAuth.instance.currentUser.emailVerified) {
( await _auth.signInWithEmailAndPassword(
email: email.trim(), password: password,)).user;
// User user = result.user;
}
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'invalid-email':
{
return 'Email is not valid';
}
case 'user-disabled':
{
return 'Account is not active';
}
case 'user-not-found':
{
return 'No user found';
}
case 'wrong-password':
{
return 'wrong password';
}
default:
{
return 'Unexpected error!';
}
}
}
return null;
}
It looks different because I changed it like it was before that so I can check if maybe it was on the changes it do because it runs at this point.
You should check email verification within you're sign-in method, and if the email was verified then return instance.signInWithEmailAndPassword.
full code:
Future<String> signIN(String email, String password) async {
try {
if(FirebaseAuth.instance.currentUser.emailVerified) {
( await _auth.signInWithEmailAndPassword(
email: email.trim(), password: password,)).user;
return "success";
// User user = result.user;
}
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'invalid-email':
{
return 'Email is not valid';
}
case 'user-disabled':
{
return 'Account is not active';
}
case 'user-not-found':
{
return 'No user found';
}
case 'wrong-password':
{
return 'wrong password';
}
default:
{
return 'Unexpected error!';
}
}
}
return return "error";;
}
so every moment when signIN calling it would check email verification and if it verified it would work if it isn't it will return "error" or other problem variants, and you can listen to response so when it gives you an error you should return a snackBar, if it returns "success" then you would navigate.
Solution of logout issue:
onPressed: () {
FirebaseAuth.instance.signOut().then((){
Navigator.pushNamedAndRemoveUntil(context, LoginScreen.route (route) => false);
});

flutter ClientException in http requests

This is the function containing the request :
Future<String> getRequest(String serviceName, Map<String, String> a) async {
var responseBody = '{"data": "", "status": "NOK"}';
try {
http.Response response =
await http.get(_urlBase + '$_serverApi$serviceName', headings: a);
if (response.statusCode == 200) {
responseBody = response.body;
}
} catch (e) {
// An error was received
throw new Exception("GET ERROR");
}
return responseBody;
}
and this is where i call it :
void _confirm() async {
if (_formKey.currentState.saveAndValidate()) {
print(_formKey.currentState.value);
Map<String, String> c =
Map<String, String>.from(_formKey.currentState.value);
// just below
var a = await auth.getRequest('se_connecter', c);
print(a);
} else {
print(_formKey.currentState.value);
print("validation failed");
}
}
everytime i try it, the code in the try bloc fails, and it throws the exception (ClientException after i removed try and catch bloc)
This the exception stacktrace :
I/flutter (10979): #0 IOClient.send
package:http/src/io_client.dart:65
I/flutter (10979): <asynchronous suspension>
I/flutter (10979): #1 BaseClient._sendUnstreamed
package:http/src/base_client.dart:176
I/flutter (10979): #2 BaseClient.get
package:http/src/base_client.dart:35
I/flutter (10979): #3 get.<anonymous closure>
package:http/http.dart:46
I/flutter (10979): #4 _withClient
package:http/http.dart:166
I/flutter (10979): #5 get
package:http/http.dart:46
I/flutter (10979): #6 getRequest
package:event_app/auth.dart:125
I/flutter (10979): #7 ConnectPageState._confirm
package:event_app/pages/connect_page.dart:28
I/flutter (10979): #8 _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:706
I/flutter (10979): #9 _InkResponseState.build.<anonymous closure>
package:flutter/…/material/ink_well.dart:789
I/flutter (10979): #10 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:182
I/flutter (10979): #11 TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:486
I/flutter (10979): #12 BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:264
I/flutter (10979): #13 BaseTapGestureRecognizer.
In my case (sometimes instead of blank appeared the error "HttpException: Connection closed before full header was received") the call was to an https address using Microsoft Internet Information Services as backend, in the SSL settings of the website in IIS i had mistakenly set "Client certificates: Accept" instead of "Client certificates: Ignore", setting "Ignore" solved the problem.
Solved, the problem was the ssl encryption, so i removed it from my backend.