Repository: django-import-export/django-import-export

Issue:
`filter_queryset` with invalid field causes UI crash on export
**Describe the bug**

Run export with invalid field name via Admin UI and the crash screen is shown.


**To Reproduce**

Add the following to `BookResource` in `tests/core/admin.py`:

```python
    def filter_export(self, queryset, **kwargs):
        return queryset.select_related("x")
```

Then export books via the Admin UI.


**Versions (please complete the following information):**
 - Django Import Export: 4.0.0-beta
 - Python 3.8
 - Django 5.0

**Expected behavior**

It would be ideal to present a suitable error message to the user, instead of crashing the page.

**Screenshots**

![Screenshot 2023-12-20 at 15 28 19](https://github.com/django-import-export/django-import-export/assets/6249838/92a8a2ad-405b-4331-8d49-f944e08541f8)




Discussion:
is this a simple try block solution? Or are my instincts failing me?

Yes, it is because we are not catching `FieldError`.  This should be caught and returned to the user as an error message.  Similar issue to #1722.

Resolving patch:
diff --git a/import_export/admin.py b/import_export/admin.py
--- a/import_export/admin.py
+++ b/import_export/admin.py
@@ -7,7 +7,7 @@
 from django.contrib.admin.models import ADDITION, CHANGE, DELETION, LogEntry
 from django.contrib.auth import get_permission_codename
 from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import PermissionDenied
+from django.core.exceptions import FieldError, PermissionDenied
 from django.forms import MultipleChoiceField, MultipleHiddenInput
 from django.http import HttpResponse, HttpResponseRedirect
 from django.shortcuts import render
@@ -739,21 +739,25 @@ def export_action(self, request):
             else:
                 queryset = self.get_export_queryset(request)
 
-            export_data = self.get_export_data(
-                file_format,
-                queryset,
-                request=request,
-                encoding=self.to_encoding,
-                export_form=form,
-            )
-            content_type = file_format.get_content_type()
-            response = HttpResponse(export_data, content_type=content_type)
-            response["Content-Disposition"] = 'attachment; filename="%s"' % (
-                self.get_export_filename(request, queryset, file_format),
-            )
+            try:
+                export_data = self.get_export_data(
+                    file_format,
+                    queryset,
+                    request=request,
+                    encoding=self.to_encoding,
+                    export_form=form,
+                )
+                content_type = file_format.get_content_type()
+                response = HttpResponse(export_data, content_type=content_type)
+                response["Content-Disposition"] = 'attachment; filename="%s"' % (
+                    self.get_export_filename(request, queryset, file_format),
+                )
+
+                post_export.send(sender=None, model=self.model)
+                return response
+            except FieldError as e:
+                messages.error(request, str(e))
 
-            post_export.send(sender=None, model=self.model)
-            return response
         context = self.init_request_context_data(request, form)
         request.current_app = self.admin_site.name
         return TemplateResponse(request, [self.export_template_name], context=context)


Test patch:
diff --git a/tests/core/tests/admin_integration/test_export.py b/tests/core/tests/admin_integration/test_export.py
--- a/tests/core/tests/admin_integration/test_export.py
+++ b/tests/core/tests/admin_integration/test_export.py
@@ -15,6 +15,7 @@
 from django.contrib.admin.sites import AdminSite
 from django.contrib.admin.views.main import ChangeList
 from django.contrib.auth.models import User
+from django.core.exceptions import FieldError
 from django.http import HttpRequest
 from django.test import RequestFactory
 from django.test.testcases import TestCase
@@ -159,6 +160,21 @@ def test_get_export_form_single_resource(self):
         self.assertIn("CategoryResource", str(response.content))
         self.assertNotIn('select name="resource"', str(response.content))
 
+    def test_get_export_FieldError(self):
+        # issue 1723
+        with mock.patch("import_export.resources.Resource.export") as mock_export:
+            mock_export.side_effect = FieldError("some unknown error")
+            data = {
+                "format": "0",
+                "resource": 1,
+                "booknameresource_id": True,
+                "booknameresource_name": True,
+            }
+            response = self.client.post("/admin/core/book/export/", data)
+        self.assertEqual(response.status_code, 200)
+        target_msg = "Some unknown error"
+        self.assertIn(target_msg, str(response.content))
+
     def test_export_second_resource(self):
         response = self.client.get("/admin/core/book/export/")
         self.assertEqual(response.status_code, 200)