[webview_flutter] Add support for passing a failing url (#2763)

diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md
index 36dc43f..1a3bfdb 100644
--- a/packages/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.22
+
+* Add support for passing a failing url.
+
 ## 0.3.21
 
 * Enable programmatic scrolling using Android's WebView.scrollTo & iOS WKWebView.scrollView.contentOffset.
diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
index f61a9d3..474435c 100644
--- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
+++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
@@ -14,6 +14,7 @@
 import android.webkit.WebResourceRequest;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
+import androidx.annotation.RequiresApi;
 import androidx.webkit.WebResourceErrorCompat;
 import androidx.webkit.WebViewClientCompat;
 import io.flutter.plugin.common.MethodChannel;
@@ -124,11 +125,13 @@
     methodChannel.invokeMethod("onPageFinished", args);
   }
 
-  private void onWebResourceError(final int errorCode, final String description) {
+  private void onWebResourceError(
+      final int errorCode, final String description, final String failingUrl) {
     final Map<String, Object> args = new HashMap<>();
     args.put("errorCode", errorCode);
     args.put("description", description);
     args.put("errorType", FlutterWebViewClient.errorCodeToString(errorCode));
+    args.put("failingUrl", failingUrl);
     methodChannel.invokeMethod("onWebResourceError", args);
   }
 
@@ -181,13 +184,13 @@
       public void onReceivedError(
           WebView view, WebResourceRequest request, WebResourceError error) {
         FlutterWebViewClient.this.onWebResourceError(
-            error.getErrorCode(), error.getDescription().toString());
+            error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
       }
 
       @Override
       public void onReceivedError(
           WebView view, int errorCode, String description, String failingUrl) {
-        FlutterWebViewClient.this.onWebResourceError(errorCode, description);
+        FlutterWebViewClient.this.onWebResourceError(errorCode, description, failingUrl);
       }
 
       @Override
@@ -223,18 +226,19 @@
 
       // This method is only called when the WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR feature is
       // enabled. The deprecated method is called when a device doesn't support this.
+      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
       @SuppressLint("RequiresFeature")
       @Override
       public void onReceivedError(
           WebView view, WebResourceRequest request, WebResourceErrorCompat error) {
         FlutterWebViewClient.this.onWebResourceError(
-            error.getErrorCode(), error.getDescription().toString());
+            error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
       }
 
       @Override
       public void onReceivedError(
           WebView view, int errorCode, String description, String failingUrl) {
-        FlutterWebViewClient.this.onWebResourceError(errorCode, description);
+        FlutterWebViewClient.this.onWebResourceError(errorCode, description, failingUrl);
       }
 
       @Override
diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart
index a8a2196..1632964 100644
--- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart
+++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart
@@ -685,8 +685,13 @@
       final WebResourceError error = await errorCompleter.future;
       expect(error, isNotNull);
 
-      if (Platform.isIOS) expect(error.domain, isNotNull);
-      if (Platform.isAndroid) expect(error.errorType, isNotNull);
+      if (Platform.isIOS) {
+        expect(error.domain, isNotNull);
+        expect(error.failingUrl, isNull);
+      } else if (Platform.isAndroid) {
+        expect(error.errorType, isNotNull);
+        expect(error.failingUrl, 'https://www.notawebsite..com');
+      }
     });
 
     testWidgets('onWebResourceError is not called with valid url',
diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart
index 238d25b..0f848ec 100644
--- a/packages/webview_flutter/lib/platform_interface.dart
+++ b/packages/webview_flutter/lib/platform_interface.dart
@@ -107,6 +107,7 @@
     @required this.description,
     this.domain,
     this.errorType,
+    this.failingUrl,
   })  : assert(errorCode != null),
         assert(description != null);
 
@@ -139,6 +140,12 @@
   ///
   /// This will never be `null` on Android, but can be `null` on iOS.
   final WebResourceErrorType errorType;
+
+  /// Gets the URL for which the resource request was made.
+  ///
+  /// This value is not provided on iOS. Alternatively, you can keep track of
+  /// the last values provided to [WebViewPlatformController.loadUrl].
+  final String failingUrl;
 }
 
 /// Interface for talking to the webview's platform implementation.
diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart
index a75dee3..348b225 100644
--- a/packages/webview_flutter/lib/src/webview_method_channel.dart
+++ b/packages/webview_flutter/lib/src/webview_method_channel.dart
@@ -49,6 +49,7 @@
             errorCode: call.arguments['errorCode'],
             description: call.arguments['description'],
             domain: call.arguments['domain'],
+            failingUrl: call.arguments['failingUrl'],
             errorType: call.arguments['errorType'] == null
                 ? null
                 : WebResourceErrorType.values.firstWhere(
diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml
index 26e4fbc..c65dac0 100644
--- a/packages/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/pubspec.yaml
@@ -1,6 +1,6 @@
 name: webview_flutter
 description: A Flutter plugin that provides a WebView widget on Android and iOS.
-version: 0.3.21
+version: 0.3.22
 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter
 
 environment: