Merge pull request #2065 from pbiering/delay-on-exception

Delay on exception
This commit is contained in:
Peter Bieringer
2026-04-03 07:51:17 +02:00
committed by GitHub
3 changed files with 28 additions and 1 deletions

View File

@@ -36,6 +36,7 @@ import pprint
import pstats import pstats
import random import random
import time import time
import traceback
import zlib import zlib
from http import client from http import client
from typing import Iterable, List, Mapping, Tuple, Union from typing import Iterable, List, Mapping, Tuple, Union
@@ -574,6 +575,10 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
except PermissionError as e: except PermissionError as e:
logger.error("PermissionError: %s", e) logger.error("PermissionError: %s", e)
status, headers, answer, xml_request = httputils.INTERNAL_SERVER_ERROR status, headers, answer, xml_request = httputils.INTERNAL_SERVER_ERROR
except Exception as e:
logger.error("Exception: %s", e)
logging.error("%s", traceback.format_exc())
status, headers, answer, xml_request = httputils.INTERNAL_SERVER_ERROR
# Profiling # Profiling
if self._profiling_per_request: if self._profiling_per_request:

View File

@@ -3,7 +3,7 @@
# Copyright © 2008 Pascal Halter # Copyright © 2008 Pascal Halter
# Copyright © 2008-2017 Guillaume Ayoub # Copyright © 2008-2017 Guillaume Ayoub
# Copyright © 2017-2021 Unrud <unrud@outlook.com> # Copyright © 2017-2021 Unrud <unrud@outlook.com>
# Copyright © 2025-2025 Peter Bieringer <pb@bieringer.de> # Copyright © 2025-2026 Peter Bieringer <pb@bieringer.de>
# #
# This library is free software: you can redistribute it and/or modify # This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Radicale. If not, see <http://www.gnu.org/licenses/>. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
import os
from http import client from http import client
from radicale import httputils, types from radicale import httputils, types
@@ -33,4 +34,7 @@ class ApplicationPartOptions(ApplicationBase):
"Allow": ", ".join( "Allow": ", ".join(
name[3:] for name in dir(self) if name.startswith("do_")), name[3:] for name in dir(self) if name.startswith("do_")),
"DAV": httputils.DAV_HEADERS} "DAV": httputils.DAV_HEADERS}
if 'PYTEST_VERSION' in os.environ and 'PYTEST_RADICALE_RAISE_GENERIC_ERROR' in os.environ:
# trigger special test case
raise ValueError('PYTEST_RADICALE_RAISE_GENERIC_ERROR')
return client.OK, headers, None, None return client.OK, headers, None, None

View File

@@ -720,6 +720,24 @@ permissions: RrWw""")
_, headers, _ = self.request("OPTIONS", "/", check=200) _, headers, _ = self.request("OPTIONS", "/", check=200)
assert "DAV" in headers assert "DAV" in headers
def test_server_error_delay_basic(self) -> None:
"""Trigger a server error and check delay."""
delay = .3
delay_min = delay * 0.9 # no random jitter during test
delay_max = delay + 0.2 # no random jitter during test
if sys.platform == "darwin": # no reliable sleep times
delay_max = delay_max * 1.5
self.configure({"server": {"delay_on_error": delay}})
os.environ["PYTEST_RADICALE_RAISE_GENERIC_ERROR"] = "1"
time_begin = datetime.datetime.now()
_, headers, answer = self.request("OPTIONS", "/", check=500)
time_end = datetime.datetime.now()
time_delta = (time_end - time_begin).total_seconds()
assert time_delta > delay_min
assert time_delta < delay_max
del os.environ["PYTEST_RADICALE_RAISE_GENERIC_ERROR"]
def test_delete_collection(self) -> None: def test_delete_collection(self) -> None:
"""Delete a collection.""" """Delete a collection."""
self.mkcalendar("/calendar.ics/") self.mkcalendar("/calendar.ics/")