Repository: django/django

Issue:
# Fixed #36246 -- Caught `GDALException` in `BaseGeometryWidget.deserialize`.

#### Trac ticket number
<!-- Replace XXXXX with the corresponding Trac ticket number, or delete the line and write "N/A" if this is a trivial PR. -->

ticket-36246

#### Branch description
@sarahboyce Thank you for providing the test code for this ticket.

#### Checklist
- [x] This PR targets the `main` branch. <!-- Backports will be evaluated and done by mergers, when necessary. -->
- [x] The commit message is written in past tense, mentions the ticket number, and ends with a period.
- [x] I have checked the "Has patch" ticket flag in the Trac system.
- [x] I have added or updated relevant tests.
- [ ] I have added or updated relevant docs, including release notes if applicable.
- [ ] I have attached screenshots in both light and dark modes for any UI changes.


Implementation patch:
diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py
index 1fd31530c135..bf6be709ed3a 100644
--- a/django/contrib/gis/forms/fields.py
+++ b/django/contrib/gis/forms/fields.py
@@ -1,5 +1,4 @@
 from django import forms
-from django.contrib.gis.gdal import GDALException
 from django.contrib.gis.geos import GEOSException, GEOSGeometry
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext_lazy as _
@@ -41,10 +40,7 @@ def to_python(self, value):
 
         if not isinstance(value, GEOSGeometry):
             if hasattr(self.widget, "deserialize"):
-                try:
-                    value = self.widget.deserialize(value)
-                except GDALException:
-                    value = None
+                value = self.widget.deserialize(value)
             else:
                 try:
                     value = GEOSGeometry(value)
diff --git a/django/contrib/gis/forms/widgets.py b/django/contrib/gis/forms/widgets.py
index 55895ae9f362..c091d3fcfc20 100644
--- a/django/contrib/gis/forms/widgets.py
+++ b/django/contrib/gis/forms/widgets.py
@@ -2,6 +2,7 @@
 
 from django.conf import settings
 from django.contrib.gis import gdal
+from django.contrib.gis.gdal import GDALException
 from django.contrib.gis.geometry import json_regex
 from django.contrib.gis.geos import GEOSException, GEOSGeometry
 from django.forms.widgets import Widget
@@ -36,7 +37,7 @@ def serialize(self, value):
     def deserialize(self, value):
         try:
             return GEOSGeometry(value)
-        except (GEOSException, ValueError, TypeError) as err:
+        except (GEOSException, GDALException, ValueError, TypeError) as err:
             logger.error("Error creating geometry from value '%s' (%s)", value, err)
         return None
 


Test patch:
diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py
index c351edaaad5a..b6068948f358 100644
--- a/tests/gis_tests/test_geoforms.py
+++ b/tests/gis_tests/test_geoforms.py
@@ -435,6 +435,19 @@ def test_get_context_attrs(self):
         context = widget.get_context("geometry", None, None)
         self.assertEqual(context["geom_type"], "Geometry")
 
+    def test_invalid_values(self):
+        bad_inputs = [
+            "POINT(5)",
+            "MULTI   POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))",
+            "BLAH(0 0, 1 1)",
+            '{"type": "FeatureCollection", "features": ['
+            '{"geometry": {"type": "Point", "coordinates": [508375, 148905]}, '
+            '"type": "Feature"}]}',
+        ]
+        for input in bad_inputs:
+            with self.subTest(input=input):
+                self.assertIsNone(BaseGeometryWidget().deserialize(input))
+
     def test_subwidgets(self):
         widget = forms.BaseGeometryWidget()
         self.assertEqual(