Android Volley Request Identity onErrorResponse Section
Asked Answered
S

7

12
public void getTestDats(String unique_id) {
    final String tag = "testList";
    String url = Constants.BASE_URL + "test_module.php";
    Map<String, String> params = new HashMap<String, String>();
    params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
    params.put("unique_id", unique_id);//1,2,3,4,5
    DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            switch (response.optInt("unique_id")) {
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }
        }
    }, new ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
                //I want to know which unique_id request is failed 
        }
    });
    loginRequest.setRetryPolicy(new DefaultRetryPolicy(20000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    AppController.getInstance().addToRequestQueue(loginRequest, tag);
} 

I'm trying to identity which request is failed with having unique_id.

I'm calling getTestDats("1") function with unique_id. And function called 10 times and all the api call in addToRequestQueue.

When API go into Success part its working as per code. But when API go into Error part I didn't identity the request. Is there any way to know my request param so I can retry with particular unique_id request.

Smasher answered 25/7, 2016 at 11:15 Comment(1)
When you are calling request, at that time store unique id in one global variable and then on error you can easily use itCharmainecharmane
S
3

set a field in loginRequest and in onErrorResponse access the field like loginRequest.getUniqueId()

Alternatively, create a seperate class that implements Response.Listener and ErrorListener

Response Listener class:

public class MyReponseListener implements Response.Listener<JSONOBject>{
    private long uniqId;
    public MyResponseListener(long uniqId){
        this.uniqId = uniqId;
    }

    @Override
    public void onResponse(JSONObject response) {
        System.out.println("response for uniqId " + uniqId);
        // do your other chit chat
    }
}

ErrorListener class:

public class MyErrorListener implements ErrorListener{
        private long uniqId;
        public MyErrorListener(long uniqId){
            this.uniqId = uniqId;
        }

        @Override
        public void onErrorResponse(VolleyError error) {
             System.out.println("Error for uniqId : " + uniqId);
        }
}

Now call it like:

DataRequest loginRequest = new DataRequest(Method.POST, url, params, new MyResponeListener(uniqId), new MyErrorListener(uniqId));

Now if you want some code of the calling class to be accessible in the ErrorListener class then do the following: 1. In calling class put the codes you want to access in methods 2. Create an interface with those method 3. The calling class will implement that interface 4. Pass the interface to constructor of the MyErrorListener or MyResponseListener

for example an activity calls the volley request, on error you want to show a message. put that show error codes in a method:

public void showMessage(int errorCode){
    //message according to code
}

now create an interface

public interface errorMessageInterface{
    void showMessage(int errorCode);
}

the activity will implement errorMessageInterface and pass this to the constructor of MyErrorListener and save it in a field.

Inside onErrorResponse, you will call

field.showMessage()
Smokechaser answered 28/7, 2016 at 5:28 Comment(0)
B
3

You can parse error response in the same way as you parse success response. I use similar solution in my projects.

public class VolleyErrorParser {
    private VolleyError mError;
    private String mBody;
    private int mUniqueId = -1;
    public VolleyErrorParser(VolleyError e){
        mError = e;
        parseAnswer();
        parseBody();
    }

    private void parseBody() {
        if (mBody==null)
            return;
        try{
            JSONObject response = new JSONObject(mBody);
            mUniqueId = response.getOptInt("unique_id");

        }catch (JSONException e){
            e.printStackTrace();
        }
    }

    private void parseAnswer() {
        if (mError!=null&&mError.networkResponse!=null&&mError.networkResponse.data!=null){
            mBody = new String(mError.networkResponse.data);
        }
    }
    public String getBody(){
        return mBody;
    }
    public int getUniqueId(){
        return mUniqueId;
    }
}

Use:

...
, new ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            int id = new VolleyErrorParse(error).getUniqueId();
            switch (id) {
                case -1:
                     //unique id not found in the answer
                     break;
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }        
        }
    }
...
Battlefield answered 29/7, 2016 at 23:34 Comment(0)
D
1

Just add this code to identify which type of error you are facing.Add this in your onError() method :

         if (error instanceof TimeoutError) {
            Log.e(TAG, "TimeoutError");
        } else if (error instanceof NoConnectionError) {
            Log.e(TAG,"tNoConnectionError");
        } else if (error instanceof AuthFailureError) {
            Log.e(TAG,"AuthFailureError");
        } else if (error instanceof ServerError) {
            Log.e(TAG,"ServerError");
        } else if (error instanceof NetworkError) {
            Log.e(TAG,"NetworkError");
        } else if (error instanceof ParseError) {
            Log.e(TAG,"ParseError");
        }
Dub answered 28/7, 2016 at 5:8 Comment(0)
T
1

Log the unique_id before making a request i.e; after params.put("unique_id", unique_id);//1,2,3,4,5. And also once you get the response in onResponse() method. And cross verify what exactly is happening.

Theocritus answered 28/7, 2016 at 5:25 Comment(0)
M
1

most of the solutions here will "work" but they are too complex .. for me :) here is the simplest option with least code change I can think of:

...
final Map<String, String> params = new HashMap<String, String>();
    params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
params.put("unique_id", unique_id);//1,2,3,4,5
DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            switch (params.get("unique_id")) {
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }
        }
...
Moreover answered 30/7, 2016 at 21:27 Comment(0)
H
1

All the above answers seem to be correct.But i recommend you to do this in an optimized way. If you will add error handling code in all onErrorResponse() then it will create duplication. So create a seperate method in Utils or some other class and just call that method by passing error object to the method. Also you can inflate some dialog or toast to display an error message.

public static void handleError(final Context context, String alertTitle,
                               Exception exception, String logTag) {
    if (context != null) {
        if (exception instanceof TimeoutError)
            message = context.getString(R.string.TimeoutError);
        else if (exception instanceof NoConnectionError)
            message = context.getString(R.string.NoConnectionError);
        else if (exception instanceof AuthFailureError)
            message = context.getString(R.string.AuthFailureError);
        else if (exception instanceof ServerError)
            message = context.getString(R.string.ServerError);
        else if (exception instanceof NetworkError)
            message = context.getString(R.string.NetworkError);
        else if (exception instanceof ParseError)
            message = context.getString(R.string.ParseError);        

            message = exception.getMessage();


                DialogHelper.showCustomAlertDialog(context, null,
                        alertTitle, message, "ok",
                        new OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {

                            }
                        }, null, null);


        }
    }
Honeywell answered 2/8, 2016 at 4:12 Comment(0)
M
1

I think you have to make one conman method on Base class. As given bellow which I used in my code for calling php web api

    /**
 * <h1>  Use for calling volley webService </h1>
 *
 * @param cContext         Context of activity from where you call the webService
 * @param mMethodType      Should be POST or GET
 * @param mMethodname      Name of the method you want to call
 * @param URL              Url of your webService
 * @param mMap             Key Values pairs
 * @param initialTimeoutMs Timeout of webService in milliseconds
 * @param shouldCache      Web Api response are stored in catch(true) or not(false)
 * @param maxNumRetries    maximum number in integer for retries to execute webService
 * @param isCancelable     set true if you set cancel progressDialog by user event
 * @param aActivity        pass your activity object
 */

public void callVolley(final Context cContext, String mMethodType, final String mMethodname, String URL,
                       final HashMap<String, String> mMap, int initialTimeoutMs, boolean shouldCache, int maxNumRetries,
                       Boolean isProgressDailogEnable, Boolean isCancelable, final Activity aActivity) {

    mMap.put("version_key_android",BuildConfig.VERSION_NAME+"");
    if (!isOnline(cContext)) {
        //showErrorDailog(aActivity, Constant.PleaseCheckInternetConnection, R.drawable.icon);
    } else {
        StringRequest jsObjRequest;
        int reqType = 0;
        String RequestURL = URL.trim();
        queue = Volley.newRequestQueue(cContext);

        if (isProgressDailogEnable) {
            customLoaderDialog = new CustomLoaderDialog(cContext);
            customLoaderDialog.show(isCancelable);

            customLoaderDialog.dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    //  finish();
                }
            });
        }
        if (mMethodType.trim().equalsIgnoreCase("GET"))
            reqType = com.android.volley.Request.Method.GET;
        else if (mMethodType.trim().equalsIgnoreCase("POST"))
            reqType = com.android.volley.Request.Method.POST;

        if (RequestURL.equals(""))
            RequestURL = Constant.BASE_URL;
        else
            RequestURL = URL;

        if (Constant.d) Log.d("reqType", reqType + "");
        jsObjRequest = new StringRequest(reqType, RequestURL, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (Constant.d) Log.d("response==>" + mMethodname, "" + response);
                if (customLoaderDialog != null) {
                    try {
                        customLoaderDialog.hide();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                if (response == null || response.length() == 0) {
                    IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
                    iVolleyRespose.onVolleyResponse(404, response, mMethodname);
                } else {

                    JSONObject json_str;
                    try {
                        json_str = new JSONObject(response);
                        int status = json_str.getInt("status");

                        if (status == 100) {

                            AlertDialog alertDialog = new AlertDialog.Builder(aActivity).create();
                            alertDialog.setTitle(getResources().getString(R.string.app_name));
                            alertDialog.setMessage(json_str.getString("message") + "");
                            alertDialog.setCancelable(false);
                            alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                            try {
                                                Intent viewIntent =
                                                        new Intent("android.intent.action.VIEW",
                                                                Uri.parse(Constant.playStoreUrl));
                                                startActivity(viewIntent);
                                            }catch(Exception e) {
                                                Toast.makeText(getApplicationContext(),"Unable to Connect Try Again...",
                                                        Toast.LENGTH_LONG).show();
                                                e.printStackTrace();
                                            }
                                           dialog.dismiss();
                                           // return;
                                        }
                                    });
                            alertDialog.show();
                        } else {
                            IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
                            iVolleyRespose.onVolleyResponse(RESPONSE_OK, response, mMethodname);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub
                IVolleyRespose iVolleyError = (IVolleyRespose) aActivity;
                iVolleyError.onVolleyError(404, "Error", mMethodname);

                if (customLoaderDialog != null) {
                    customLoaderDialog.hide();
                }

            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                String strRequest = "";
                try {
                    strRequest = getWebservicejsObjRequestforvolley(mMethodname, mMap);
                    if (Constant.d) Log.d("Request==>", strRequest + "");
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Map<String, String> params = new HashMap<>();
                params.put("json", strRequest);

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };
        //if(Constant.d) Log.d("Request==>", jsObjRequest+"");
        jsObjRequest.setTag(mMethodname);
        jsObjRequest.setShouldCache(shouldCache);

        jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(initialTimeoutMs, maxNumRetries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(jsObjRequest);
    }
}

Please observe that here we make one interface for getting response and error. Using Interface you can get method name on both response and error so you can identify which web api is successfully called and which give error. You should extend base class to Activity and also implement Interface which you made for getting volley response. Here in above code I show how to bind interface to activity. when you call api by passing activity context.

Mesomorphic answered 3/8, 2016 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.