From b53fc5eca7728cd11e40f8fc2db53ff00d4ec514 Mon Sep 17 00:00:00 2001 From: dimitris Date: Fri, 15 May 2026 22:03:04 +0200 Subject: [PATCH] fix(webview): surface main-frame load failures in the in-app browser WebViewFragment in addedit/ is the screen the user types or navigates a URL into so it can be picked for monitoring. The WebViewClient overrides onPageStarted and onPageFinished to drive the progress bar but does not override onReceivedError, so a failed navigation (DNS, certificate, offline, 4xx/5xx) just leaves a blank page with no clue what went wrong. Add an onReceivedError override that hides the progress bar and shows a short Toast with the failure reason. Gated on request.isForMainFrame so a blocked sub-resource does not also pop a Toast. Adds webview_load_failed / webview_load_failed_with_reason strings to keep the message translatable. --- .../addedit/WebViewFragment.kt | 27 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 ++ 2 files changed, 29 insertions(+) diff --git a/app/src/main/java/com/bernaferrari/changedetection/addedit/WebViewFragment.kt b/app/src/main/java/com/bernaferrari/changedetection/addedit/WebViewFragment.kt index 80a6e63..d11ad78 100644 --- a/app/src/main/java/com/bernaferrari/changedetection/addedit/WebViewFragment.kt +++ b/app/src/main/java/com/bernaferrari/changedetection/addedit/WebViewFragment.kt @@ -1,14 +1,18 @@ package com.bernaferrari.changedetection.addedit import android.graphics.Bitmap +import android.os.Build import android.os.Bundle import android.text.Editable import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.webkit.WebResourceError +import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient +import android.widget.Toast import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProviders import androidx.navigation.findNavController @@ -60,6 +64,29 @@ class WebViewFragment : ScopedFragment() { progress?.visibility = View.GONE super.onPageFinished(view, url) } + + override fun onReceivedError( + view: WebView?, + request: WebResourceRequest?, + error: WebResourceError? + ) { + super.onReceivedError(view, request, error) + // Only surface the main-frame failure, otherwise every blocked + // sub-resource would pop a toast + if (request?.isForMainFrame != true) return + progress?.visibility = View.GONE + val description = if (Build.VERSION.SDK_INT >= 23) { + error?.description?.toString().orEmpty() + } else { + "" + } + val message = if (description.isNotBlank()) { + getString(R.string.webview_load_failed_with_reason, description) + } else { + getString(R.string.webview_load_failed) + } + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + } } close.setOnClickListener { goPreviousFragment() } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9eeb210..bfdfd00 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,6 +3,8 @@ Yes No + Page failed to load + Page failed to load: %1$s Save Cancel