Handle Volley error
Asked Answered
A

6

43

I want to handle and show some message in onErrorResponse

below is my code.

String url = MainActivity.strHostUrl+"api/delete_picture"; 
jobjDeleteImage = new JsonObjectRequest(Request.Method.POST, url, jobj, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        Log.e("Image response", response.toString());


    }
},  new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {

        Log.e("Volly Error", error.toString());

        NetworkResponse networkResponse = error.networkResponse;
        if (networkResponse != null) {
            Log.e("Status code", String.valueOf(networkResponse.statusCode));
        }
    }
});

I want to handle com.android.volley.TimeoutError and also some other error code like 404, 503 etc and Toast message here.

Albarran answered 11/7, 2014 at 14:50 Comment(3)
Possible duplicate, see my answer here: #21868429Valente
Yes but you have not handle com.android.volley.TimeoutError and I want to handle this exception and in this exception networkResponse come null.Albarran
ok - posted up a quick revisionValente
V
130

The networkResponse is null because in a TimeoutError no data is received from the server -- hence the timeout. Instead, you need generic client side strings to display when one of these events occur. You can check for the VolleyError's type using instanceof to differentiate between error types since you have no network response to work with -- for example:

@Override
public void onErrorResponse(VolleyError error) {

    if (error instanceof TimeoutError || error instanceof NoConnectionError) {
        Toast.makeText(context,
                context.getString(R.string.error_network_timeout),
                Toast.LENGTH_LONG).show();
    } else if (error instanceof AuthFailureError) {
        //TODO
    } else if (error instanceof ServerError) {
       //TODO
    } else if (error instanceof NetworkError) {
      //TODO
    } else if (error instanceof ParseError) {
       //TODO
    }
}
Valente answered 11/7, 2014 at 15:10 Comment(4)
I have not check your code but I think it will work.Albarran
Please note that NoConnectionError is not related to TimeoutError. It means that both data and WiFi are disabled. It is also important to check for NoConnectionError before checking for NetworkError, because former is the subclass of the later.Bawdry
i got 422 Unprocessable Entity from server and the above code consider it as ServerError any thoughts on thatYwis
This like 3 years late, but that's an implementation detail of the library and likely a priority matching quirk with how the instanceof op works. When an error occurs, the library creates an instance that is a subclass of VolleyError. How does the instanceof operator work you ask? Good question, give it a Google. Generally using instanceof isn't the ideal solution, but at the time this worked for me. If the server utilizes HTTP error codes correctly you should be able to just check the integer value of the error code that is generated from that individual response, and go from there.Valente
M
7

This is what I am using in my projects.

        @Override
        public void onErrorResponse(VolleyError error) {
            if(error instanceof NoConnectionError){
                ConnectivityManager cm = (ConnectivityManager)mContext
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = null;
                if (cm != null) {
                    activeNetwork = cm.getActiveNetworkInfo();
                }
                if(activeNetwork != null && activeNetwork.isConnectedOrConnecting()){
                    Toast.makeText(getActivity(), "Server is not connected to internet.",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getActivity(), "Your device is not connected to internet.",
                            Toast.LENGTH_SHORT).show();
                }
            } else if (error instanceof NetworkError || error.getCause() instanceof ConnectException 
                    || (error.getCause().getMessage() != null 
                    && error.getCause().getMessage().contains("connection"))){
                Toast.makeText(getActivity(), "Your device is not connected to internet.", 
                        Toast.LENGTH_SHORT).show();
            } else if (error.getCause() instanceof MalformedURLException){
                Toast.makeText(getActivity(), "Bad Request.", Toast.LENGTH_SHORT).show();
            } else if (error instanceof ParseError || error.getCause() instanceof IllegalStateException
                    || error.getCause() instanceof JSONException
                    || error.getCause() instanceof XmlPullParserException){
                Toast.makeText(getActivity(), "Parse Error (because of invalid json or xml).", 
                        Toast.LENGTH_SHORT).show();
            } else if (error.getCause() instanceof OutOfMemoryError){
                Toast.makeText(getActivity(), "Out Of Memory Error.", Toast.LENGTH_SHORT).show();
            }else if (error instanceof AuthFailureError){
                Toast.makeText(getActivity(), "server couldn't find the authenticated request.", 
                        Toast.LENGTH_SHORT).show();
            } else if (error instanceof ServerError || error.getCause() instanceof ServerError) {
                Toast.makeText(getActivity(), "Server is not responding.", Toast.LENGTH_SHORT).show();
            }else if (error instanceof TimeoutError || error.getCause() instanceof SocketTimeoutException
                    || error.getCause() instanceof ConnectTimeoutException 
                    || error.getCause() instanceof SocketException
                    || (error.getCause().getMessage() != null 
                    && error.getCause().getMessage().contains("Connection timed out"))) {
                Toast.makeText(getActivity(), "Connection timeout error", 
                        Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getActivity(), "An unknown error occurred.", 
                        Toast.LENGTH_SHORT).show();
            }
        }
Maller answered 15/10, 2018 at 12:35 Comment(0)
C
2

You have TimeoutError and NoConnectionError as well. Super useful.

Consultation answered 16/2, 2015 at 11:16 Comment(0)
A
0

You can handle the volley quick response with a custom volley class like this: Volley class:

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.LruCache;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

import static android.content.ContentValues.TAG;

public class VolleyClass {
    private static VolleyClass mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private Context mCtx;
    private int time = 0;

    public VolleyClass(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<>(20);

                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }

    public static synchronized VolleyClass getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new VolleyClass(context);
        }
        return mInstance;

    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        req.setRetryPolicy(new DefaultRetryPolicy(
                time,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        getRequestQueue().add(req);
    }

    private RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            //mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
         mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new OkHttpStack(new com.squareup.okhttp.OkHttpClient()));
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {

        req.setRetryPolicy(new DefaultRetryPolicy(
                time,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        getRequestQueue().add(req);
    }




    /*public ImageLoader getImageLoader() {
        return mImageLoader;
    }*/
}

Sync gradle with

compile 'com.android.volley:volley:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.8.1'

Initialise the volley class:

VolleyClass volleyClass;
 volleyClass = new VolleyClass(this);

Under onCreate then call the method for operation 1.row data:

private void serverCall() {
            final ProgressDialog mDialog = new ProgressDialog(SettingActivity.this);
            mDialog.setMessage("Please wait...");
            mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mDialog.setIndeterminate(true);
            mDialog.setCancelable(false);
            mDialog.show();

        
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, "your url", null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {

                
                mDialog.dismiss();


            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                mDialog.dismiss();

            }
        }) {
            
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json; charset=utf-8");
                headers.put("User-agent", System.getProperty("http.agent"));
                return headers;
            }

            @Override
            public Priority getPriority() {
                return Priority.IMMEDIATE;
            }
        };

        volleyClass.addToRequestQueue(jsObjRequest);

    }

private void networkCallPostData() {
    
    StringRequest stringRequest = new StringRequest(Request.Method.POST, "url",

            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.e("response", response);
                    
                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {

            System.out.println("VolleyError " + error.getMessage());
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("id",app.getAppSettings().__uId);
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            //headers.put("Content-Type", "application/json; charset=utf-8");
            headers.put("Content-Type", "multipart/form-data");
            headers.put("User-agent", System.getProperty("http.agent"));
            return headers;
        }

        @Override
        public Priority getPriority() {
            return Priority.IMMEDIATE;
        }

    };
    volleyClass.addToRequestQueue(stringRequest);
}
Aceous answered 24/1, 2018 at 12:38 Comment(0)
C
0

Read more about Volley Error handling at Android Volley example with Error Handling

Every Volley requests has two callbacks -one for success and one for failure.Based on the type of VolleyError parameter in the onErrorResponse callback developers can show a sensible message to the users as shown below

@Override
public void onErrorResponse (VolleyError error){

   if (error instanceof TimeoutError || error instanceof NoConnectionError) {
     //This indicates that the reuest has either time out or there is no connection

   } else if (error instanceof AuthFailureError) {
     // Error indicating that there was an Authentication Failure while performing the request

   } else if (error instanceof ServerError) {
     //Indicates that the server responded with a error response

   } else if (error instanceof NetworkError) {
     //Indicates that there was network error while performing the request

   } else if (error instanceof ParseError) {
      // Indicates that the server response could not be parsed

   }
}
Calcareous answered 1/5, 2018 at 10:5 Comment(0)
N
-2
/**
 * Http 访问失败
 * 
 * 
 */
@Override
public void error(VolleyError error){

     NetworkResponse response = error.networkResponse;
     if(response != null && response.data != null){
        Toast.makeText(context,"errorMessage:"+response.statusCode, Toast.LENGTH_SHORT).show();
     }else{
        String errorMessage=error.getClass().getSimpleName();       
        if(!TextUtils.isEmpty(errorMessage)){
            Toast.makeText(context,"errorMessage:"+errorMessage, Toast.LENGTH_SHORT).show();
        }
     }

}//public void error(VolleyError error) is over!  zlb
Nobie answered 23/9, 2015 at 9:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.