✨Improve error detail when re-requesting credential #285
GitHub Actions / JUnit Test Report
failed
Dec 3, 2024 in 0s
875 tests run, 868 passed, 6 skipped, 1 failed.
Annotations
Check failure on line 373 in app/tests/e2e/issuer/test_indy_credentials.py
github-actions / JUnit Test Report
test_indy_credentials.test_requesting_already_issued_credential[clean-clean-clean-clean-clean]
fastapi.exceptions.HTTPException: 404: {"detail":"Record not found: cred_ex_v20/100dd442-ac39-44f1-8e72-e8e593580bcf."}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f2dea786ae0>
method = 'post'
url = '/v1/issuer/credentials/v2-100dd442-ac39-44f1-8e72-e8e593580bcf/request'
kwargs = {}, attempt = 0, response = <Response [404 Not Found]>, code = 404
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [404 Not Found]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '404 Not Found' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/issuer/credentials/v2-100dd442-ac39-44f1-8e72-e8e593580bcf/request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
/usr/local/lib/python3.12/site-packages/httpx/_models.py:829: HTTPStatusError
The above exception was the direct cause of the following exception:
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f2dea786ae0>
tenant_admin_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f2dea784050>
faber_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f2de9f0b710>
faber_and_alice_connection = FaberAliceConnect(alice_connection_id='958da2fe-e8e0-47b3-8420-9e07472764d8', faber_connection_id='c2a2a32f-8a39-422d-8806-aec799d37035')
credential_definition_id = 'JsKC6vL9i2EQ1TbiuA6WGk:3:CL:2437:tag'
@pytest.mark.anyio
@pytest.mark.skipif(
TestMode.regression_run in TestMode.fixture_params,
reason="We don't want to modify wallet settings for regression runs",
)
async def test_requesting_already_issued_credential(
alice_member_client: RichAsyncClient,
tenant_admin_client: RichAsyncClient,
faber_client: RichAsyncClient,
faber_and_alice_connection: FaberAliceConnect,
credential_definition_id: str,
):
# First, configure Alice to not auto-complete credential flow
alice_wallet_id = get_wallet_id_from_async_client(alice_member_client)
update_request = {"extra_settings": {"ACAPY_AUTO_STORE_CREDENTIAL": False}}
update_response = await tenant_admin_client.put(
f"{TENANTS_BASE_PATH}/{alice_wallet_id}",
json=update_request,
)
assert update_response.status_code == 200
# Create credential offer
credential = {
"connection_id": faber_and_alice_connection.faber_connection_id,
"indy_credential_detail": {
"credential_definition_id": credential_definition_id,
"attributes": sample_credential_attributes,
},
"save_exchange_record": True,
}
# Send credential offer
response = await faber_client.post(
CREDENTIALS_BASE_PATH,
json=credential,
)
credential_exchange = response.json()
thread_id = credential_exchange["thread_id"]
# Wait for offer to be received
await check_webhook_state(
client=alice_member_client,
topic="credentials",
state="offer-received",
filter_map={
"thread_id": thread_id,
},
)
# Get credential exchange ID
await asyncio.sleep(0.5) # credential may take moment to reflect after webhook
response = await alice_member_client.get(
CREDENTIALS_BASE_PATH,
params={"thread_id": thread_id},
)
credential_exchange_id = (response.json())[0]["credential_exchange_id"]
# First request should succeed
request_response = await alice_member_client.post(
f"{CREDENTIALS_BASE_PATH}/{credential_exchange_id}/request",
)
assert request_response.status_code == 200
await asyncio.sleep(1) # sleep for record to update
# Second request should fail with 409
> error_response = await alice_member_client.post(
f"{CREDENTIALS_BASE_PATH}/{credential_exchange_id}/request",
)
app/tests/e2e/issuer/test_indy_credentials.py:373:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f2dea786ae0>
e = HTTPStatusError("Client error '404 Not Found' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/issuer/c...-8e72-e8e593580bcf/request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404")
url = '/v1/issuer/credentials/v2-100dd442-ac39-44f1-8e72-e8e593580bcf/request'
method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 404: {"detail":"Record not found: cred_ex_v20/100dd442-ac39-44f1-8e72-e8e593580bcf."}
shared/util/rich_async_client.py:61: HTTPException
Loading