We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Return HTTP errors in proper format
Proposer: Eric Brehault
Seconder:
# Motivation

When a page does not exist, or has an error, or is not allowed for the user, Plone returns the appropriate HTTP error (404, 500, ...), and the response is a human readable page, properly skinned, which nice for the user.
And if the requested resource is not a page (an image, a JS file, an AJAX call, etc.), Plone also returns this human readable page.
It is useless because the page will not be displayed, and it produces many problems:
- the response is very heavy,
- it involves a lot of processing (Plone will render an entire page for nothing),
- for AJAX call, the response cannot be easily interperted,
- it might produce a cascade of errors (for instance: the regular response is not supposed to be rendered via Diazo, as it is not an HTML page, but the error is rendered by Diazo, and it might produce another error).
# Proposed solution

We could display the human readable error page only if the current request `HTTP_ACCEPT` parameter contains `text/html`, in other cases, we would just return a simple JSON error reponse.
# Proposed implementation

Test the `HTTP_ACCEPT` value in `Products/CMFPlone/skins/plone_templates/standard_error_message.py`, and call the existing template or make a JSON response accordingly.
# Risks

No identified risks.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/skins/plone_templates/standard_error_message.py`
Content:
```
1 ## Script (Python) "standard_error_message"
2 ##bind container=container
3 ##bind context=context
4 ##bind namespace=
5 ##bind script=script
6 ##bind subpath=traverse_subpath
7 ##parameters=**kwargs
8 ##title=Dispatches to relevant error view
9 
10 ## by default we handle everything in 1 PageTemplate.
11 #  you could easily check for the error_type and
12 #  dispatch to an appropriate PageTemplate.
13 
14 # Check if the object is traversable, if not it might be a view, get its parent
15 # because we need to render the error on an actual content object
16 from AccessControl import Unauthorized
17 try:
18     while not hasattr(context.aq_explicit, 'restrictedTraverse'):
19         context = context.aq_parent
20 except (Unauthorized, AttributeError):
21     context = context.portal_url.getPortalObject()
22 
23 error_type = kwargs.get('error_type', None)
24 error_message = kwargs.get('error_message', None)
25 error_log_url = kwargs.get('error_log_url', None)
26 error_tb = kwargs.get('error_tb', None)
27 error_traceback = kwargs.get('error_traceback', None)
28 error_value = kwargs.get('error_value', None)
29 
30 if error_log_url:
31     error_log_id = error_log_url.split('?id=')[1]
32 else:
33     error_log_id = None
34 
35 
36 no_actions = {'folder': [], 'user': [], 'global': [], 'workflow': []}
37 error_page = context.default_error_message(
38                                 error_type=error_type,
39                                 error_message=error_message,
40                                 error_tb=error_tb,
41                                 error_value=error_value,
42                                 error_log_url=error_log_url,
43                                 error_log_id=error_log_id,
44                                 no_portlets=True,
45                                 actions=no_actions)
46 
47 return error_page
48
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/skins/plone_templates/standard_error_message.py b/Products/CMFPlone/skins/plone_templates/standard_error_message.py
--- a/Products/CMFPlone/skins/plone_templates/standard_error_message.py
+++ b/Products/CMFPlone/skins/plone_templates/standard_error_message.py
@@ -27,6 +27,10 @@
 error_traceback = kwargs.get('error_traceback', None)
 error_value = kwargs.get('error_value', None)
 
+if "text/html" not in context.REQUEST.getHeader('Accept', ''):
+    context.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
+    return '{"error_type": "{0:s}"}'.format(error_type)
+
 if error_log_url:
     error_log_id = error_log_url.split('?id=')[1]
 else:

{"golden_diff": "diff --git a/Products/CMFPlone/skins/plone_templates/standard_error_message.py b/Products/CMFPlone/skins/plone_templates/standard_error_message.py\n--- a/Products/CMFPlone/skins/plone_templates/standard_error_message.py\n+++ b/Products/CMFPlone/skins/plone_templates/standard_error_message.py\n@@ -27,6 +27,10 @@\n error_traceback = kwargs.get('error_traceback', None)\n error_value = kwargs.get('error_value', None)\n \n+if \"text/html\" not in context.REQUEST.getHeader('Accept', ''):\n+    context.REQUEST.RESPONSE.setHeader(\"Content-Type\", \"application/json\")\n+    return '{\"error_type\": \"{0:s}\"}'.format(error_type)\n+\n if error_log_url:\n     error_log_id = error_log_url.split('?id=')[1]\n else:\n", "issue": "Return HTTP errors in proper format\nProposer: Eric Brehault\nSeconder:\n# Motivation\n\nWhen a page does not exist, or has an error, or is not allowed for the user, Plone returns the appropriate HTTP error (404, 500, ...), and the response is a human readable page, properly skinned, which nice for the user.\nAnd if the requested resource is not a page (an image, a JS file, an AJAX call, etc.), Plone also returns this human readable page.\nIt is useless because the page will not be displayed, and it produces many problems:\n- the response is very heavy,\n- it involves a lot of processing (Plone will render an entire page for nothing),\n- for AJAX call, the response cannot be easily interperted,\n- it might produce a cascade of errors (for instance: the regular response is not supposed to be rendered via Diazo, as it is not an HTML page, but the error is rendered by Diazo, and it might produce another error).\n# Proposed solution\n\nWe could display the human readable error page only if the current request `HTTP_ACCEPT` parameter contains `text/html`, in other cases, we would just return a simple JSON error reponse.\n# Proposed implementation\n\nTest the `HTTP_ACCEPT` value in `Products/CMFPlone/skins/plone_templates/standard_error_message.py`, and call the existing template or make a JSON response accordingly.\n# Risks\n\nNo identified risks.\n\n", "before_files": [{"content": "## Script (Python) \"standard_error_message\"\n##bind container=container\n##bind context=context\n##bind namespace=\n##bind script=script\n##bind subpath=traverse_subpath\n##parameters=**kwargs\n##title=Dispatches to relevant error view\n\n## by default we handle everything in 1 PageTemplate.\n#  you could easily check for the error_type and\n#  dispatch to an appropriate PageTemplate.\n\n# Check if the object is traversable, if not it might be a view, get its parent\n# because we need to render the error on an actual content object\nfrom AccessControl import Unauthorized\ntry:\n    while not hasattr(context.aq_explicit, 'restrictedTraverse'):\n        context = context.aq_parent\nexcept (Unauthorized, AttributeError):\n    context = context.portal_url.getPortalObject()\n\nerror_type = kwargs.get('error_type', None)\nerror_message = kwargs.get('error_message', None)\nerror_log_url = kwargs.get('error_log_url', None)\nerror_tb = kwargs.get('error_tb', None)\nerror_traceback = kwargs.get('error_traceback', None)\nerror_value = kwargs.get('error_value', None)\n\nif error_log_url:\n    error_log_id = error_log_url.split('?id=')[1]\nelse:\n    error_log_id = None\n\n\nno_actions = {'folder': [], 'user': [], 'global': [], 'workflow': []}\nerror_page = context.default_error_message(\n                                error_type=error_type,\n                                error_message=error_message,\n                                error_tb=error_tb,\n                                error_value=error_value,\n                                error_log_url=error_log_url,\n                                error_log_id=error_log_id,\n                                no_portlets=True,\n                                actions=no_actions)\n\nreturn error_page\n", "path": "Products/CMFPlone/skins/plone_templates/standard_error_message.py"}], "after_files": [{"content": "## Script (Python) \"standard_error_message\"\n##bind container=container\n##bind context=context\n##bind namespace=\n##bind script=script\n##bind subpath=traverse_subpath\n##parameters=**kwargs\n##title=Dispatches to relevant error view\n\n## by default we handle everything in 1 PageTemplate.\n#  you could easily check for the error_type and\n#  dispatch to an appropriate PageTemplate.\n\n# Check if the object is traversable, if not it might be a view, get its parent\n# because we need to render the error on an actual content object\nfrom AccessControl import Unauthorized\ntry:\n    while not hasattr(context.aq_explicit, 'restrictedTraverse'):\n        context = context.aq_parent\nexcept (Unauthorized, AttributeError):\n    context = context.portal_url.getPortalObject()\n\nerror_type = kwargs.get('error_type', None)\nerror_message = kwargs.get('error_message', None)\nerror_log_url = kwargs.get('error_log_url', None)\nerror_tb = kwargs.get('error_tb', None)\nerror_traceback = kwargs.get('error_traceback', None)\nerror_value = kwargs.get('error_value', None)\n\nif \"text/html\" not in context.REQUEST.getHeader('Accept', ''):\n    context.REQUEST.RESPONSE.setHeader(\"Content-Type\", \"application/json\")\n    return '{\"error_type\": \"{0:s}\"}'.format(error_type)\n\nif error_log_url:\n    error_log_id = error_log_url.split('?id=')[1]\nelse:\n    error_log_id = None\n\n\nno_actions = {'folder': [], 'user': [], 'global': [], 'workflow': []}\nerror_page = context.default_error_message(\n                                error_type=error_type,\n                                error_message=error_message,\n                                error_tb=error_tb,\n                                error_value=error_value,\n                                error_log_url=error_log_url,\n                                error_log_id=error_log_id,\n                                no_portlets=True,\n                                actions=no_actions)\n\nreturn error_page\n", "path": "Products/CMFPlone/skins/plone_templates/standard_error_message.py"}]}