Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 577 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Flutter : Handling error Dio Package (404,400 etc)

#1
I'm learn searching data by ID with package **DIO** <https://pub.dev/packages/dio>, my problem is every time I'm type wrong keyword search, the app suddenly crash with debug message **404 Not Found**.

![enter image description here][1]
<br>

I know data not found because I'm type wrong keyword, but I'm already handle this with this code <br>
```
Widget _searchKeywordMahasiswa() {
return FutureBuilder<List<Mosque>>(
future: api.getMahasiswaById(_searchText),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Text(snapshot.data[index].id);
},
),
);
} else if (!snapshot.data) { <<<<<< IN THIS LINE
return Center(
child: Icon(
Icons.sentiment_very_dissatisfied,
size: 150.0,
),
);
}
return CircularProgressIndicator();
},
);
// return CircularProgressIndicator();
}
```
```
Future<List<Mosque>> getMahasiswaById(String id) async{
try {
var apiRespon = await dio.get('${Urls.BASE_API_URL}/mahasiswa/get/id/$id');
var apiResponJson = apiRespon.data;
print(apiResponJson);
return (apiResponJson['data'] as List).map((p)=>Mosque.fromJson(p)).toList();

}on DioError catch (e) { <<<<< IN THIS LINE
if(e.response.statusCode == 404){
print(e.response.statusCode);
}else{
print(e.message);
print(e.request);
}
}
}
```
> In same case my App crash too if i'm get error **400 Bad Request** And i'm already handle this error but not works.

Can you Help Me With This?


[1]:
Reply

#2
remove 'on DioError' - unfortunately there are some errors (404's, 500s...) that Dio wont't process and won't catch - had similar problem in my app.
Then change code to posted below or use some other logic to 'catch'em all' ;)

} catch (e) {

if (e is DioError) {
//handle DioError here by error type or by error code

} else {
...
}
//return empty list (you can also return custom error to be handled by Future Builder)
}

by the way you should properly handle Future Builder states: `snapshot.hasData`, empty data and `snapshot.hasError` in your future builder to prevent future crashes
Reply

#3
```
var response = await dio.delete(
url,
data: postData,
options: Options(
followRedirects: false,
validateStatus: (status) {
return status < 500;
},
headers: headers,
),
);
```

please use the code below bro,

add followRedirects, validateStatus to your code.

Reply

#4


I also had the similar type problem.

First, try to run the project from command prompt with `flutter run` see if there is occurring any problem or not.

If the command prompt is showing no problem & your app is running smoothly then you have to check the IDE. If you are using VSCode then switch to Debug is side bar, see which options are ticked in Breakpoint section. If `All Exceptions` is ticked then the debugger will pause on every exception. Uncheck both `All Exceptions` & `Uncaught Exceptions` then try refresh restart.

Hope this will solve your problem.

[![Breakpoint Section Image][1]][1]


[1]:
Reply

#5
I had the same problem it was just changing my interceptor that worked

import 'package:dio/dio.dart';

class CustomInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
print("onRequest");
return super.onRequest(options, handler);
}

@override
Future onResponse(Response response, ResponseInterceptorHandler handler) {
print("onResponse");
return null;
}

@override
Future onError(DioError err, ErrorInterceptorHandler handler) async {
print("onError: ${err.response.statusCode}");
return handler.next(err); // <--- THE TIP IS HERE
}
}

Reply

#6
You can manage timeout exception using `DioClient`:

There are two way, declaring customized `Option` then assign to the `Dio` or directly assign below `option` to it, but I prefer to separate these type of `Option` for oriented need.
You can set a condition to get all problems except 400 (success) response, but you have to aware of **Connection Timeout**, so here a integrated in Dio way:

class YourRepositary {
Dio dioClient;

YourRepositary() {
if (dioClient == null) {
BaseOptions options = new BaseOptions(
baseUrl: "YOUR_APIs_BASE_URL",
receiveDataWhenStatusError: true,
connectTimeout: 30000, // 30 seconds
receiveTimeout: 30000 // 30 seconds
);

dioClient = new Dio(options);
}
}

Future<ProductResponseModel> getProduct(var productRequestInputDto) async {
try {
Response response = await dio.post("/api/getProduct", data: productRequestInputDto);
final ProductResponseModel _productModel = ProductResponseModel.fromJson(response.data);
return _productModel ;
} on DioError catch (ex) {
if(ex.type == DioErrorType.CONNECT_TIMEOUT){
throw Exception("Connection Timeout Exception");
}
throw Exception(ex.message);
}
}

}

At the end, below example demonstrate how you handle Timeout exception or even handled by your backend 500 error in API call:


void getProduct(){
ProductRequestInputDto productRequest = new ProductRequestInputDto(productId: "666");

var requestBody = jsonEncode(loginRequest);
debugPrint("Request Data : $requestBody");

_apiRepositary.getProduct(requestBody).then((response){
debugPrint("Login Success $response");
//manage your response here
},
onError: (exception){
//Handle exception message
if(exception.message != null ){
debugPrint(exception.message); // Here you get : "Connection Timeout Exception" or even handled 500 errors on your backend.
}
},
);
}

To conclusion, it's all about `receiveDataWhenStatusError: true`, in the option of Dio.
Reply

#7
dynamic _decodeErrorResponse(dynamic e) {
dynamic data = {"statusCode": -1, "message": "Unknown Error"};
if (e is DioError) {
if (e.type == DioErrorType.response) {
final response = e.response;
try {
if (response != null && response.data != null) {
final Map responseData =
json.decode(response.data as String) as Map;
data["message"] = responseData['message'] as String;
data["statusCode"] = response.statusCode;
}
} catch (e) {
data["message"] = "Internal Error Catch";
}
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
data["message"] = "Request timeout";
data["statusCode"] = 408;
} else if (e.error is SocketException) {
data["message"] = "No Internet Connection!";
}
}
return data;
}
Reply

#8
Found a solution. This code worked for me.

try {
Dio dio = Dio();
var res = await dio.download(
url + 'fg',
savePath.path + "/filename.bin",
onReceiveProgress: (count, total) {
progress(count, total);
},
);
} on DioError catch (e) {
if (e.type == DioErrorType.response) {
print('catched');
return;
}
if (e.type == DioErrorType.connectTimeout) {
print('check your connection');
return;
}

if (e.type == DioErrorType.receiveTimeout) {
print('unable to connect to the server');
return;
}

if (e.type == DioErrorType.other) {
print('Something went wrong');
return;
}
print(e);
} catch (e) {
print(e);
}
Reply

#9
The selected answer is working perfectly fine. But if someone still getting an error after adding those lines. You can try this one.

Add content type to the field.


dio.FormData formData = dio.FormData.fromMap({
"file": await dio.MultipartFile.fromFile(
file.path,
filename: fileName,
contentType: MediaType('audio', 'mp4'),
),
Reply

#10
Error is with this URL string pattern `${Urls.BASE_API_URL}/mahasiswa/get/id/$id`

you can not use . operator and access the inner value from any object inside "". You can store the exact url in other variable and use it in that line. Code should be as follows.


Future<List<Mosque>> getMahasiswaById(String id) async{
try {
var baseURL = Urls.BASE_API_URL;
var apiRespon = await dio.get('${baseURL}/mahasiswa/get/id/$id');
var apiResponJson = apiRespon.data;
print(apiResponJson);
return (apiResponJson['data'] as List).map((p)=>Mosque.fromJson(p)).toList();

}on DioError catch (e) { <<<<< IN THIS LINE
if(e.response.statusCode == 404){
print(e.response.statusCode);
}else{
print(e.message);
print(e.request);
}
}
}
============ UPDATE ============

You can use `.` operator as follows,


var apiRespon = await dio.get('${Urls.BASE_API_URL}/mahasiswa/get/id/$id');


Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through