We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
SSR Sentry error reporting
At the time of writing, 7 times this has happened:
```
HTTPError: 500 Server Error: Internal Server Error for url: http://ssr/ssr/SPA
  File "django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "newrelic/hooks/framework_django.py", line 544, in wrapper
    return wrapped(*args, **kwargs)
  File "django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "ratelimit/decorators.py", line 30, in _wrapped
    return fn(*args, **kw)
  File "kuma/search/views.py", line 34, in search
    return render(request, 'search/react.html', context)
  File "django/shortcuts.py", line 30, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "django_jinja/backend.py", line 106, in render
    return mark_safe(self.template.render(context))
  File "newrelic/api/function_trace.py", line 121, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/app/kuma/search/jinja2/search/react.html", line 3, in top-level template code
    {% set query = request.GET.get('q') %}
  File "/app/jinja2/react_base.html", line 103, in top-level template code
    {% block document_head %}{% endblock %}
  File "/app/kuma/search/jinja2/search/react.html", line 20, in block "document_head"
    results)|safe }}
  File "kuma/wiki/templatetags/ssr.py", line 50, in render_react
    return server_side_render(component_name, data)
  File "kuma/wiki/templatetags/ssr.py", line 133, in server_side_render
    response.raise_for_status()
  File "requests/models.py", line 940, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
```
https://sentry.prod.mozaws.net/operations/mdn-prod/issues/6448273/?query=is:unresolved

It's "fine". The SSR service is bound to be imperfect. What's worrying is that there are no Node errors in Sentry. It's just too unlikely that there have been no exceptions in the SSR Node service. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kuma/wiki/templatetags/ssr.py`
Content:
```
1 
2 
3 import json
4 import os
5 from functools import lru_cache
6 
7 import requests
8 import requests.exceptions
9 from django.conf import settings
10 from django_jinja import library
11 
12 
13 @lru_cache()
14 def get_localization_data(locale):
15     """
16     Read the frontend string catalog for the specified locale, parse
17     it as JSON, and return the resulting dict. The returned values
18     are cached so that we don't have to read files all the time.
19     """
20     path = os.path.join(settings.BASE_DIR,
21                         'static', 'jsi18n',
22                         locale, 'react.json')
23     with open(path, 'r') as f:
24         return json.load(f)
25 
26 
27 @library.global_function
28 def render_react(component_name, locale, url, document_data, ssr=True):
29     """
30     Render a script tag to define the data and any other HTML tags needed
31     to enable the display of a React-based UI. By default, this does
32     server side rendering, falling back to client-side rendering if
33     the SSR attempt fails. Pass False as the second argument to do
34     client-side rendering unconditionally.
35 
36     Note that we are not defining a generic Jinja template tag here.
37     The code in this file is specific to Kuma's React-based UI.
38     """
39     localization_data = get_localization_data(locale)
40 
41     data = {
42         'locale': locale,
43         'stringCatalog': localization_data['catalog'],
44         'pluralExpression': localization_data['plural'],
45         'url': url,
46         'documentData': document_data,
47     }
48 
49     if ssr:
50         return server_side_render(component_name, data)
51     else:
52         return client_side_render(component_name, data)
53 
54 
55 def _render(component_name, html, script, needs_serialization=False):
56     """A utility function used by both client side and server side rendering.
57     Returns a string that includes the specified HTML and a serialized
58     form of the state dict, in the format expected by the client-side code
59     in kuma/javascript/src/index.jsx.
60     """
61     if needs_serialization:
62         assert isinstance(script, dict), type(script)
63         script = json.dumps(script).replace('</', '<\\/')
64     else:
65         script = 'JSON.parse({})'.format(script)
66 
67     return (
68         '<div id="react-container" data-component-name="{}">{}</div>\n'
69         '<script>window._react_data = {};</script>\n'
70     ).format(component_name, html, script)
71 
72 
73 def client_side_render(component_name, data):
74     """
75     Output an empty <div> and a script with complete state so that
76     the UI can be rendered on the client-side.
77     """
78     return _render(component_name, '', data, needs_serialization=True)
79 
80 
81 def server_side_render(component_name, data):
82     """
83     Pre-render the React UI to HTML and output it in a <div>, and then
84     also pass the necessary serialized state in a <script> so that
85     React on the client side can sync itself with the pre-rendred HTML.
86 
87     If any exceptions are thrown during the server-side rendering, we
88     fall back to client-side rendering instead.
89     """
90     url = '{}/{}'.format(settings.SSR_URL, component_name)
91     timeout = settings.SSR_TIMEOUT
92     # Try server side rendering
93     try:
94         # POST the document data as JSON to the SSR server and we
95         # should get HTML text (encoded as plain text) in the body
96         # of the response
97         response = requests.post(url,
98                                  headers={'Content-Type': 'application/json'},
99                                  data=json.dumps(data).encode('utf8'),
100                                  timeout=timeout)
101 
102         # Even though we've got fully rendered HTML now, we still need to
103         # send the document data along with it so that React can sync its
104         # state on the client side with what is in the HTML. When rendering
105         # a document page, the data includes long strings of HTML that
106         # we can get away without duplicating. So as an optimization when
107         # component_name is "document", we're going to make a copy of the
108         # data (because the original belongs to our caller) and delete those
109         # strings from the copy.
110         #
111         # WARNING: This optimization can save 20kb in data transfer
112         # for typical pages, but it requires us to be very careful on
113         # the frontend. If any components render conditionally based on
114         # the state of bodyHTML, tocHTML or quickLinkHTML, then they will
115         # render differently on the client than during SSR, and the hydrate
116         # will not just work cleanly, and those components will re-render
117         # with empty strings. This has already caused Bug 1558308, and
118         # I've commented it out because the benefit in file size doesn't
119         # seem worth the risk of client-side bugs.
120         #
121         # As an alternative, it ought to be possible to extract the HTML
122         # strings from the SSR'ed document and rebuild the document object
123         # on the client right before we call hydrate(). So if you uncomment
124         # the lines below, you should also edit kuma/javascript/src/index.jsx
125         # to extract the HTML from the document as well.
126         #
127         # if component_name == 'document':
128         #     data = data.copy()
129         #     data['documentData'] = data['documentData'].copy()
130         #     data['documentData'].update(bodyHTML='',
131         #                                 tocHTML='',
132         #                                 quickLinksHTML='')
133         response.raise_for_status()
134         result = response.json()
135         return _render(component_name, result['html'], result['script'])
136 
137     except requests.exceptions.ConnectionError:
138         print("Connection error contacting SSR server.")
139         print("Falling back to client side rendering.")
140         return client_side_render(component_name, data)
141     except requests.exceptions.ReadTimeout:
142         print("Timeout contacting SSR server.")
143         print("Falling back to client side rendering.")
144         return client_side_render(component_name, data)
145
```
--- 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/kuma/wiki/templatetags/ssr.py b/kuma/wiki/templatetags/ssr.py
--- a/kuma/wiki/templatetags/ssr.py
+++ b/kuma/wiki/templatetags/ssr.py
@@ -134,11 +134,7 @@
         result = response.json()
         return _render(component_name, result['html'], result['script'])
 
-    except requests.exceptions.ConnectionError:
-        print("Connection error contacting SSR server.")
-        print("Falling back to client side rendering.")
-        return client_side_render(component_name, data)
-    except requests.exceptions.ReadTimeout:
-        print("Timeout contacting SSR server.")
+    except requests.exceptions.RequestException as exception:
+        print(f"{exception.__class__} error contacting SSR server.")
         print("Falling back to client side rendering.")
         return client_side_render(component_name, data)

{"golden_diff": "diff --git a/kuma/wiki/templatetags/ssr.py b/kuma/wiki/templatetags/ssr.py\n--- a/kuma/wiki/templatetags/ssr.py\n+++ b/kuma/wiki/templatetags/ssr.py\n@@ -134,11 +134,7 @@\n         result = response.json()\n         return _render(component_name, result['html'], result['script'])\n \n-    except requests.exceptions.ConnectionError:\n-        print(\"Connection error contacting SSR server.\")\n-        print(\"Falling back to client side rendering.\")\n-        return client_side_render(component_name, data)\n-    except requests.exceptions.ReadTimeout:\n-        print(\"Timeout contacting SSR server.\")\n+    except requests.exceptions.RequestException as exception:\n+        print(f\"{exception.__class__} error contacting SSR server.\")\n         print(\"Falling back to client side rendering.\")\n         return client_side_render(component_name, data)\n", "issue": "SSR Sentry error reporting\nAt the time of writing, 7 times this has happened:\r\n```\r\nHTTPError: 500 Server Error: Internal Server Error for url: http://ssr/ssr/SPA\r\n  File \"django/core/handlers/exception.py\", line 41, in inner\r\n    response = get_response(request)\r\n  File \"django/core/handlers/base.py\", line 187, in _get_response\r\n    response = self.process_exception_by_middleware(e, request)\r\n  File \"django/core/handlers/base.py\", line 185, in _get_response\r\n    response = wrapped_callback(request, *callback_args, **callback_kwargs)\r\n  File \"newrelic/hooks/framework_django.py\", line 544, in wrapper\r\n    return wrapped(*args, **kwargs)\r\n  File \"django/views/decorators/cache.py\", line 57, in _wrapped_view_func\r\n    response = view_func(request, *args, **kwargs)\r\n  File \"django/views/decorators/http.py\", line 40, in inner\r\n    return func(request, *args, **kwargs)\r\n  File \"ratelimit/decorators.py\", line 30, in _wrapped\r\n    return fn(*args, **kw)\r\n  File \"kuma/search/views.py\", line 34, in search\r\n    return render(request, 'search/react.html', context)\r\n  File \"django/shortcuts.py\", line 30, in render\r\n    content = loader.render_to_string(template_name, context, request, using=using)\r\n  File \"django/template/loader.py\", line 68, in render_to_string\r\n    return template.render(context, request)\r\n  File \"django_jinja/backend.py\", line 106, in render\r\n    return mark_safe(self.template.render(context))\r\n  File \"newrelic/api/function_trace.py\", line 121, in dynamic_wrapper\r\n    return wrapped(*args, **kwargs)\r\n  File \"jinja2/environment.py\", line 1008, in render\r\n    return self.environment.handle_exception(exc_info, True)\r\n  File \"jinja2/environment.py\", line 780, in handle_exception\r\n    reraise(exc_type, exc_value, tb)\r\n  File \"/app/kuma/search/jinja2/search/react.html\", line 3, in top-level template code\r\n    {% set query = request.GET.get('q') %}\r\n  File \"/app/jinja2/react_base.html\", line 103, in top-level template code\r\n    {% block document_head %}{% endblock %}\r\n  File \"/app/kuma/search/jinja2/search/react.html\", line 20, in block \"document_head\"\r\n    results)|safe }}\r\n  File \"kuma/wiki/templatetags/ssr.py\", line 50, in render_react\r\n    return server_side_render(component_name, data)\r\n  File \"kuma/wiki/templatetags/ssr.py\", line 133, in server_side_render\r\n    response.raise_for_status()\r\n  File \"requests/models.py\", line 940, in raise_for_status\r\n    raise HTTPError(http_error_msg, response=self)\r\n```\r\nhttps://sentry.prod.mozaws.net/operations/mdn-prod/issues/6448273/?query=is:unresolved\r\n\r\nIt's \"fine\". The SSR service is bound to be imperfect. What's worrying is that there are no Node errors in Sentry. It's just too unlikely that there have been no exceptions in the SSR Node service. \n", "before_files": [{"content": "\n\nimport json\nimport os\nfrom functools import lru_cache\n\nimport requests\nimport requests.exceptions\nfrom django.conf import settings\nfrom django_jinja import library\n\n\n@lru_cache()\ndef get_localization_data(locale):\n    \"\"\"\n    Read the frontend string catalog for the specified locale, parse\n    it as JSON, and return the resulting dict. The returned values\n    are cached so that we don't have to read files all the time.\n    \"\"\"\n    path = os.path.join(settings.BASE_DIR,\n                        'static', 'jsi18n',\n                        locale, 'react.json')\n    with open(path, 'r') as f:\n        return json.load(f)\n\n\n@library.global_function\ndef render_react(component_name, locale, url, document_data, ssr=True):\n    \"\"\"\n    Render a script tag to define the data and any other HTML tags needed\n    to enable the display of a React-based UI. By default, this does\n    server side rendering, falling back to client-side rendering if\n    the SSR attempt fails. Pass False as the second argument to do\n    client-side rendering unconditionally.\n\n    Note that we are not defining a generic Jinja template tag here.\n    The code in this file is specific to Kuma's React-based UI.\n    \"\"\"\n    localization_data = get_localization_data(locale)\n\n    data = {\n        'locale': locale,\n        'stringCatalog': localization_data['catalog'],\n        'pluralExpression': localization_data['plural'],\n        'url': url,\n        'documentData': document_data,\n    }\n\n    if ssr:\n        return server_side_render(component_name, data)\n    else:\n        return client_side_render(component_name, data)\n\n\ndef _render(component_name, html, script, needs_serialization=False):\n    \"\"\"A utility function used by both client side and server side rendering.\n    Returns a string that includes the specified HTML and a serialized\n    form of the state dict, in the format expected by the client-side code\n    in kuma/javascript/src/index.jsx.\n    \"\"\"\n    if needs_serialization:\n        assert isinstance(script, dict), type(script)\n        script = json.dumps(script).replace('</', '<\\\\/')\n    else:\n        script = 'JSON.parse({})'.format(script)\n\n    return (\n        '<div id=\"react-container\" data-component-name=\"{}\">{}</div>\\n'\n        '<script>window._react_data = {};</script>\\n'\n    ).format(component_name, html, script)\n\n\ndef client_side_render(component_name, data):\n    \"\"\"\n    Output an empty <div> and a script with complete state so that\n    the UI can be rendered on the client-side.\n    \"\"\"\n    return _render(component_name, '', data, needs_serialization=True)\n\n\ndef server_side_render(component_name, data):\n    \"\"\"\n    Pre-render the React UI to HTML and output it in a <div>, and then\n    also pass the necessary serialized state in a <script> so that\n    React on the client side can sync itself with the pre-rendred HTML.\n\n    If any exceptions are thrown during the server-side rendering, we\n    fall back to client-side rendering instead.\n    \"\"\"\n    url = '{}/{}'.format(settings.SSR_URL, component_name)\n    timeout = settings.SSR_TIMEOUT\n    # Try server side rendering\n    try:\n        # POST the document data as JSON to the SSR server and we\n        # should get HTML text (encoded as plain text) in the body\n        # of the response\n        response = requests.post(url,\n                                 headers={'Content-Type': 'application/json'},\n                                 data=json.dumps(data).encode('utf8'),\n                                 timeout=timeout)\n\n        # Even though we've got fully rendered HTML now, we still need to\n        # send the document data along with it so that React can sync its\n        # state on the client side with what is in the HTML. When rendering\n        # a document page, the data includes long strings of HTML that\n        # we can get away without duplicating. So as an optimization when\n        # component_name is \"document\", we're going to make a copy of the\n        # data (because the original belongs to our caller) and delete those\n        # strings from the copy.\n        #\n        # WARNING: This optimization can save 20kb in data transfer\n        # for typical pages, but it requires us to be very careful on\n        # the frontend. If any components render conditionally based on\n        # the state of bodyHTML, tocHTML or quickLinkHTML, then they will\n        # render differently on the client than during SSR, and the hydrate\n        # will not just work cleanly, and those components will re-render\n        # with empty strings. This has already caused Bug 1558308, and\n        # I've commented it out because the benefit in file size doesn't\n        # seem worth the risk of client-side bugs.\n        #\n        # As an alternative, it ought to be possible to extract the HTML\n        # strings from the SSR'ed document and rebuild the document object\n        # on the client right before we call hydrate(). So if you uncomment\n        # the lines below, you should also edit kuma/javascript/src/index.jsx\n        # to extract the HTML from the document as well.\n        #\n        # if component_name == 'document':\n        #     data = data.copy()\n        #     data['documentData'] = data['documentData'].copy()\n        #     data['documentData'].update(bodyHTML='',\n        #                                 tocHTML='',\n        #                                 quickLinksHTML='')\n        response.raise_for_status()\n        result = response.json()\n        return _render(component_name, result['html'], result['script'])\n\n    except requests.exceptions.ConnectionError:\n        print(\"Connection error contacting SSR server.\")\n        print(\"Falling back to client side rendering.\")\n        return client_side_render(component_name, data)\n    except requests.exceptions.ReadTimeout:\n        print(\"Timeout contacting SSR server.\")\n        print(\"Falling back to client side rendering.\")\n        return client_side_render(component_name, data)\n", "path": "kuma/wiki/templatetags/ssr.py"}], "after_files": [{"content": "\n\nimport json\nimport os\nfrom functools import lru_cache\n\nimport requests\nimport requests.exceptions\nfrom django.conf import settings\nfrom django_jinja import library\n\n\n@lru_cache()\ndef get_localization_data(locale):\n    \"\"\"\n    Read the frontend string catalog for the specified locale, parse\n    it as JSON, and return the resulting dict. The returned values\n    are cached so that we don't have to read files all the time.\n    \"\"\"\n    path = os.path.join(settings.BASE_DIR,\n                        'static', 'jsi18n',\n                        locale, 'react.json')\n    with open(path, 'r') as f:\n        return json.load(f)\n\n\n@library.global_function\ndef render_react(component_name, locale, url, document_data, ssr=True):\n    \"\"\"\n    Render a script tag to define the data and any other HTML tags needed\n    to enable the display of a React-based UI. By default, this does\n    server side rendering, falling back to client-side rendering if\n    the SSR attempt fails. Pass False as the second argument to do\n    client-side rendering unconditionally.\n\n    Note that we are not defining a generic Jinja template tag here.\n    The code in this file is specific to Kuma's React-based UI.\n    \"\"\"\n    localization_data = get_localization_data(locale)\n\n    data = {\n        'locale': locale,\n        'stringCatalog': localization_data['catalog'],\n        'pluralExpression': localization_data['plural'],\n        'url': url,\n        'documentData': document_data,\n    }\n\n    if ssr:\n        return server_side_render(component_name, data)\n    else:\n        return client_side_render(component_name, data)\n\n\ndef _render(component_name, html, script, needs_serialization=False):\n    \"\"\"A utility function used by both client side and server side rendering.\n    Returns a string that includes the specified HTML and a serialized\n    form of the state dict, in the format expected by the client-side code\n    in kuma/javascript/src/index.jsx.\n    \"\"\"\n    if needs_serialization:\n        assert isinstance(script, dict), type(script)\n        script = json.dumps(script).replace('</', '<\\\\/')\n    else:\n        script = 'JSON.parse({})'.format(script)\n\n    return (\n        '<div id=\"react-container\" data-component-name=\"{}\">{}</div>\\n'\n        '<script>window._react_data = {};</script>\\n'\n    ).format(component_name, html, script)\n\n\ndef client_side_render(component_name, data):\n    \"\"\"\n    Output an empty <div> and a script with complete state so that\n    the UI can be rendered on the client-side.\n    \"\"\"\n    return _render(component_name, '', data, needs_serialization=True)\n\n\ndef server_side_render(component_name, data):\n    \"\"\"\n    Pre-render the React UI to HTML and output it in a <div>, and then\n    also pass the necessary serialized state in a <script> so that\n    React on the client side can sync itself with the pre-rendred HTML.\n\n    If any exceptions are thrown during the server-side rendering, we\n    fall back to client-side rendering instead.\n    \"\"\"\n    url = '{}/{}'.format(settings.SSR_URL, component_name)\n    timeout = settings.SSR_TIMEOUT\n    # Try server side rendering\n    try:\n        # POST the document data as JSON to the SSR server and we\n        # should get HTML text (encoded as plain text) in the body\n        # of the response\n        response = requests.post(url,\n                                 headers={'Content-Type': 'application/json'},\n                                 data=json.dumps(data).encode('utf8'),\n                                 timeout=timeout)\n\n        # Even though we've got fully rendered HTML now, we still need to\n        # send the document data along with it so that React can sync its\n        # state on the client side with what is in the HTML. When rendering\n        # a document page, the data includes long strings of HTML that\n        # we can get away without duplicating. So as an optimization when\n        # component_name is \"document\", we're going to make a copy of the\n        # data (because the original belongs to our caller) and delete those\n        # strings from the copy.\n        #\n        # WARNING: This optimization can save 20kb in data transfer\n        # for typical pages, but it requires us to be very careful on\n        # the frontend. If any components render conditionally based on\n        # the state of bodyHTML, tocHTML or quickLinkHTML, then they will\n        # render differently on the client than during SSR, and the hydrate\n        # will not just work cleanly, and those components will re-render\n        # with empty strings. This has already caused Bug 1558308, and\n        # I've commented it out because the benefit in file size doesn't\n        # seem worth the risk of client-side bugs.\n        #\n        # As an alternative, it ought to be possible to extract the HTML\n        # strings from the SSR'ed document and rebuild the document object\n        # on the client right before we call hydrate(). So if you uncomment\n        # the lines below, you should also edit kuma/javascript/src/index.jsx\n        # to extract the HTML from the document as well.\n        #\n        # if component_name == 'document':\n        #     data = data.copy()\n        #     data['documentData'] = data['documentData'].copy()\n        #     data['documentData'].update(bodyHTML='',\n        #                                 tocHTML='',\n        #                                 quickLinksHTML='')\n        response.raise_for_status()\n        result = response.json()\n        return _render(component_name, result['html'], result['script'])\n\n    except requests.exceptions.RequestException as exception:\n        print(f\"{exception.__class__} error contacting SSR server.\")\n        print(\"Falling back to client side rendering.\")\n        return client_side_render(component_name, data)\n", "path": "kuma/wiki/templatetags/ssr.py"}]}