0
votes

The sample of the following code is a GET request form retrieving user email from Spring server that throws exceptions when the user is not valid.

The problem that I can't catch the error from the body meaning, I can see it if I explicitly print the Body message.

The purpose is to view the error message to the client if there's something wrong with the details

  Future<bool> fetchUser(username) async {

        setLoading(true);
        await RestRequest(username).fetchUser().then((data) {

          if (data.statusCode == 200) {
            setUser(User.fromJson(json.decode(data.body)));
            //print("got to ok code");
          }
          else{
           //print(data.headers.);
          }
     }
    ).catchError((error) {
      //TODO: handle errors
       errorMessage = jsonDecode(error.toString())["message"];
      throw(errorMessage);
    });

And when I print data.body I see the error.

 I/flutter (10871): {"timestamp":"2020-05-20T08:40:40.205+0000","status":500,"error":"Internal Server Error","message":"could not find user for email:a","trace":"acs.logic.EntityNotFoundException: could not find user for email:a\r\n\tat acs.logic.UserServiceWithDB.getUser(UserServiceWithDB.java:71)\r\n\tat acs.logic.UserServiceWithDB.login(UserServiceWithDB.java:79)\r\n\tat acs.logic.UserServiceWithDB$$FastClassBySpringCGLIB$$879f73c1.invoke(<generated>)\r\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)\r\n\tat acs.logic.UserServiceWithDB$$EnhancerBySpringCGLIB$$647f71c3.login(<generated>)\r\n\tat acs.rest.UserController.login(UserController.java:29)\r\n\tat jdk.internal.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)\r\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base/java.lang.reflect.Method.inv

FetchUser function

import 'package:http/http.dart' as http;

class RestRequest {

   final String userEmail;
   final int port=8091;


  RestRequest(this.userEmail);


  Future<http.Response> fetchUser() {
    print(this.userEmail);
    return http.get('http://192.168.1.30:8091/acs/users/login/${this.userEmail}');
  }
}
1
Could you add the code how you use the fetchUser? Do you use a FutureBuilder for this?Flutter Explained
If 200, you have to parse the JSON body response and check if body["status"]==500 then print(body["error"])camillo777
a edited the postaviomer
Look like You have the correct code in the flutter app, but the server returns the message about the wrong data.Makdir
Hello @aviomer can you please check what is the value that you receive in data.statusCode ? Thank youcamillo777

1 Answers

0
votes

I made a working sample to show you how to parse the body. After checking for statusCode 200, the jsonDecode the "body" and look for the field "status"; if it is "500" then get the "error" field:

import 'package:flutter/material.dart';
import 'dart:convert';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final String body = """
  {"timestamp":"2020-05-20T08:40:40.205+0000","status":500,"error":"Internal Server Error","message":"could not find user for email:a","trace":""}
  """;

  Future<String> fetchUser(username) async {
    print("fetchUser");
    Map res = jsonDecode(body);

    print(res);
    if (res["status"] == 500) {
      return res["error"].toString();
    } else {
      //setUser(User.fromJson(json.decode(data.body)));
      return "got to ok code";
    }
  }

  @override
  Widget build(BuildContext context) {
    print("build");
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: FutureBuilder(
              future: fetchUser("Bill"),
              builder: (_, snap) {
                if (snap.hasData) return Text("${snap.data}");
                return Text("wait");
              }),
        ),
      ),
    );
  }
}