Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ A Docker Compose setup is present that will spin up a temporary MySQL database
and run tests against it:

```shell
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit
docker compose -f docker-compose.test.yml up --build notifier --abort-on-container-exit
```

## Status
Expand Down
105 changes: 51 additions & 54 deletions notifier/wikidot.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def module(

# Try the module a few times with increasing delay in case it fails
response = None
last_error: Optional[requests.ConnectionError] = None
for attempt_count in range(self.MODULE_ATTEMPT_LIMIT):
attempt_delay = 2**attempt_count * self.PAGINATION_DELAY_S
logger.debug(
Expand All @@ -153,41 +154,42 @@ def module(
),
cookies={"wikidot_token7": token7},
)
except ConnectionError as error:
will_retry = attempt_count < self.MODULE_ATTEMPT_LIMIT
except requests.ConnectionError as error:
last_error = error
logger.debug(
"Module connection failed %s",
{
"attempt_number": attempt_count + 1,
"attempt_delay_s": attempt_delay,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
exc_info=error,
)
if will_retry:
continue
raise OngoingConnectionError from error
continue
except Exception:
logger.error(
"Unexpected error during module connection %s",
{
"attempt_number": attempt_count + 1,
"wiki_id": wiki_id,
"module_name": module_name,
},
exc_info=True,
)
raise

if 500 <= response_raw.status_code <= 599:
will_retry = attempt_count < self.MODULE_ATTEMPT_LIMIT
if will_retry:
logger.warning(
"Wikidot internal failure, retrying in 10 seconds %s",
{
"attempt_number": attempt_count + 1,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
"status_code": response_raw.status_code,
"response_text": response_raw.text,
},
)
time.sleep(10)
continue
logger.warning(
"Wikidot might be down %s", {"response": response}
"Wikidot internal failure, retrying in 10 seconds %s",
{
"attempt_number": attempt_count + 1,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"status_code": response_raw.status_code,
"response_text": response_raw.text,
},
)
raise Wikibork
time.sleep(10)
continue

try:
response = response_raw.json()
Expand All @@ -209,25 +211,26 @@ def module(
and response["message"]
== "An error occurred while processing the request."
):
will_retry = attempt_count < self.MODULE_ATTEMPT_LIMIT
if will_retry:
logger.warning(
"Wikidot internal failure, retrying in 10 seconds %s",
{
"attempt_number": attempt_count + 1,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
)
time.sleep(10)
continue
logger.warning(
"Wikidot might be down %s", {"response": response}
"Wikidot internal failure, retrying in 10 seconds %s",
{
"attempt_number": attempt_count + 1,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
},
)
raise Wikibork
time.sleep(10)
continue

# Successful response, break to parsing
break
else:
# All retries exhausted
if last_error is not None:
raise OngoingConnectionError from last_error
logger.warning(
"Wikidot might be down %s", {"response": response}
)
raise Wikibork
assert response is not None

if response["status"] == "no_thread":
Expand Down Expand Up @@ -390,7 +393,6 @@ def login(self, username: str, password: str) -> None:

for attempt_count in range(self.MODULE_ATTEMPT_LIMIT):
attempt_delay = 2**attempt_count * self.PAGINATION_DELAY_S
will_retry = attempt_count < self.MODULE_ATTEMPT_LIMIT
time.sleep(attempt_delay)
response = self.post(
"https://www.wikidot.com/default--flow/login__LoginPopupScreen",
Expand All @@ -408,12 +410,9 @@ def login(self, username: str, password: str) -> None:
"attempt_number": attempt_count + 1,
"attempt_delay_s": attempt_delay,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
)
if will_retry:
continue
raise Wikibork
continue

if response.status_code != 200:
logger.warning(
Expand All @@ -423,13 +422,14 @@ def login(self, username: str, password: str) -> None:
"attempt_number": attempt_count + 1,
"attempt_delay_s": attempt_delay,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
)
if will_retry:
continue
raise OngoingConnectionError
continue
break
else:
if response.status_code >= 500:
raise Wikibork
raise OngoingConnectionError

if "The login and password do not match" in response.text:
raise RuntimeError("Failed to login")
Expand Down Expand Up @@ -513,7 +513,6 @@ def get_page_id(self, wiki_id: str, slug: str) -> int:
page_text = None
for attempt_count in range(self.MODULE_ATTEMPT_LIMIT):
attempt_delay = 2**attempt_count * self.PAGINATION_DELAY_S
will_retry = attempt_count < self.MODULE_ATTEMPT_LIMIT
time.sleep(attempt_delay)
response = self._session.get(page_url)

Expand All @@ -525,12 +524,9 @@ def get_page_id(self, wiki_id: str, slug: str) -> int:
"attempt_number": attempt_count + 1,
"attempt_delay_s": attempt_delay,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
)
if will_retry:
continue
raise Wikibork
continue

if response.status_code != 200:
logger.warning(
Expand All @@ -541,15 +537,16 @@ def get_page_id(self, wiki_id: str, slug: str) -> int:
"attempt_number": attempt_count + 1,
"attempt_delay_s": attempt_delay,
"max_attempts": self.MODULE_ATTEMPT_LIMIT,
"will_retry": will_retry,
},
)
if will_retry:
continue
raise OngoingConnectionError
continue

page_text = response.text
break
else:
if response.status_code == 500:
raise Wikibork
raise OngoingConnectionError
assert page_text is not None

return int(
Expand Down
Loading