Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛(backend) submit for signature handle timeout and exception on delete signing procedure #924

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to

### Fixed

- Handle timeout and exception in `submit_for_signature` to
update the contract without the outdated references
- Improve signature backend `handle_notification` error catching
- Allow to cancel an enrollment order linked to an archived course run

Expand Down Expand Up @@ -50,7 +52,6 @@ and this project adheres to

- Do not update OpenEdX enrollment if this one is already
up-to-date on the remote lms
-

## [2.4.0] - 2024-06-21

Expand Down
7 changes: 7 additions & 0 deletions src/backend/joanie/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@ class CertificateGenerationError(Exception):
Exception raised when the certificate generation process fails due to the order not meeting
all specified conditions.
"""


class BackendTimeout(Exception):
"""
Exception raised when a backend reaches the timeout set when we are waiting
for the response.
"""
18 changes: 14 additions & 4 deletions src/backend/joanie/core/models/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from urllib3.util import Retry

from joanie.core import enums
from joanie.core.exceptions import CertificateGenerationError
from joanie.core.exceptions import BackendTimeout, CertificateGenerationError
from joanie.core.fields.schedule import OrderPaymentScheduleEncoder
from joanie.core.flows.order import OrderFlow
from joanie.core.models.accounts import User
Expand All @@ -38,6 +38,7 @@
from joanie.core.utils import issuers, webhooks
from joanie.core.utils.payment_schedule import generate as generate_payment_schedule
from joanie.signature.backends import get_signature_backend
from joanie.signature.exceptions import DeleteSignatureProcedureFailed

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -965,9 +966,18 @@ def submit_for_signature(self, user: User):
)

if should_be_resubmitted:
backend_signature.delete_signing_procedure(
contract.signature_backend_reference
)
# The signature provider may delay confirming deletion. If timeout occurs, reset
# submission values, as the signature provider will delete them. In an edge case, the
# reference `contract.signature_backend_reference` cannot be used and may already
# be deleted causing a 'not found' error from the signature provider.
try:
backend_signature.delete_signing_procedure(
contract.signature_backend_reference
)
except (BackendTimeout, DeleteSignatureProcedureFailed):
pass
contract.reset_submission_for_signature()
was_already_submitted = False

# We want to submit or re-submit the contract for signature in three cases:
# 1- the contract was never submitted for signature before
Expand Down
17 changes: 16 additions & 1 deletion src/backend/joanie/signature/backends/lex_persona.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
from django.core.exceptions import ValidationError

import requests
from requests.exceptions import ReadTimeout
from rest_framework.request import Request
from sentry_sdk import capture_exception

from joanie.core import enums, models
from joanie.core.exceptions import BackendTimeout
from joanie.core.utils.contract import order_has_organization_owner
from joanie.signature import exceptions
from joanie.signature.backends.base import BaseSignatureBackend
Expand Down Expand Up @@ -528,7 +530,20 @@ def delete_signing_procedure(self, reference_id: str):
url = f"{base_url}/api/workflows/{reference_id}"
headers = {"Authorization": f"Bearer {token}"}

response = requests.delete(url, headers=headers, timeout=timeout)
try:
response = requests.delete(url, headers=headers, timeout=timeout)
except ReadTimeout as exception:
logger.error(
exception,
extra={
"context": {
"signature_backend_reference": reference_id,
}
},
)
raise BackendTimeout(
f"Deletion request is taking longer than expected for reference: {reference_id}"
) from exception
Comment on lines +544 to +546
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By reading that, I feel BackendTimeout exception duplicates the ReadTimeout exception. We could simply raise the received exception.

Suggested change
raise BackendTimeout(
f"Deletion request is taking longer than expected for reference: {reference_id}"
) from exception
raise exception


if not response.ok:
logger.error(
Expand Down
Loading