Android WebViewClient onReceivedError is not called for a 404 error

22,164

Solution 1

I had to override WebViewClient.onReceivedHttpError() instead of WebViewClient.onReceivedError().

    @Override
    public void onReceivedHttpError(final WebView view, final WebResourceRequest request, WebResourceResponse errorResponse) {
        final int statusCode;
        // SDK < 21 does not provide statusCode
        if (Build.VERSION.SDK_INT < 21) {
            statusCode = STATUS_CODE_UNKNOWN;
        } else {
            statusCode = errorResponse.getStatusCode();
        }

        Log().d(LOG_TAG, "[onReceivedHttpError]" + statusCode);
    }

From the WebClient documentation:

/**
 * Notify the host application that an HTTP error has been received from the server while
 * loading a resource.  HTTP errors have status codes &gt;= 400.  This callback will be called
 * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to
 * perform minimum required work in this callback. Note that the content of the server
 * response may not be provided within the <b>errorResponse</b> parameter.
 * @param view The WebView that is initiating the callback.
 * @param request The originating request.
 * @param errorResponse Information about the error occured.
 */
public void onReceivedHttpError(
        WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
}

Solution 2

I had the same issue today,

The problem: onPageFinished is called always. If there is an error it will be called after onErrorReceived.

This is the solution I've found:

holder.image.setWebViewClient(new WebViewClient() {

    private boolean error;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {

        super.onPageStarted(view, url, favicon);
        error = false;
    }

    @Override
    public void onReceivedError( WebView view, int errorCode, String description, String failingUrl)  {

        error = true;
        System.out.println("description error" + description);
        view.setVisibility( View.GONE );
    }

    @Override
    public void onPageFinished(WebView view, String url) {

        if (!error) {
            view.setVisibility( View.VISIBLE );
        }
        error = false;
    }

});

Solution 3

@Neeraj is on the right track, but my app allows a refresh of the webview, so I need to clear the error state before any new URL load. Furthermore, the error flag must be stored as a data member on the parent activity so that it persists during onPageStart() and onPageFinish()--those methods can be called after onError().

public class MyActivity extends Activity {
    private boolean isError;
    ...
    protected void onResume() {
        super.onResume();
        isError = false;
        myWebView.loadUrl(myUrl);
    }

    public class MyWebViewClient extends WebViewClient {
    /**
     * can be called even after error (embedded images?), so error flag must keep state as data-member in activity, cleared by activity before each loadUrl();          
     */
      @Override
      public void onPageFinished(WebView view, String url) {
        if (!isError)
            showContent();
      }

      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        isError = true;
        showError();
      }
Share:
22,164
ganesh
Author by

ganesh

Android developer

Updated on July 24, 2022

Comments

  • ganesh
    ganesh almost 2 years

    hi
    In a list view i have an webview which should load a image file from the server,when there is no image present i need a dummy image .I tried

    holder.image.setWebViewClient(new WebViewClient()
    {
                      @Override
                    public void onReceivedError( WebView view, int errorCode, String description, String failingUrl) 
                    {
    
                        System.out.println("description error" + description);
                        view.setVisibility( View.GONE );
    
                    }
    
                    @Override
                    public void onPageFinished(WebView view, String url) {
    
                        view.setVisibility( View.VISIBLE );
    
    
                    }
    
    
       }); 
    

    I have this webview with an dummy image in a FrameLayout, onPageFinished listener is called after every image url is loaded, but onReceivedError is not called for a url which produce a 404 error.Any guess how to do it.

    • Peter Knego
      Peter Knego about 13 years
      It seems that it can not be done: stackoverflow.com/questions/5124052/…
    • ganesh
      ganesh about 13 years
      I tried using HttpClient and on checking the HttpStatus i have loaded the url if the HttpStatus return error message then I restrain from loading url, instead display a no-image png.Is this method is a cumbersome,can any one suggest an alternative for this.
    • Machine
      Machine over 12 years
      It can't be done with WebView, you can however use the basic HTTPClient and check for the response code. Here is a link on how to do that: stackoverflow.com/questions/2592843/…
  • Michael
    Michael over 7 years
    onReceivedHttpError isn't available if API level < 23
  • soger
    soger over 4 years
    This should be a comment under the question, not a response.