Skip to content

Issue #3845 fix : auto-store failure going to done state#3999

Merged
swcurran merged 3 commits intoopenwallet-foundation:mainfrom
sonivijayk:sonivijayk/fix/issue-3845-credential-auto-store-failure-handling
Jan 13, 2026
Merged

Issue #3845 fix : auto-store failure going to done state#3999
swcurran merged 3 commits intoopenwallet-foundation:mainfrom
sonivijayk:sonivijayk/fix/issue-3845-credential-auto-store-failure-handling

Conversation

@sonivijayk
Copy link
Contributor

Issue Summary

  1. Applied check to prevent auto-store failures from moving v2.0 credential exchanges to done
  2. Added storage failures logic to retry by keeping state credential-received and saving error_msg
  3. Abandon unrecoverable auto-store failures and log proper message under exception
  4. Updated test

Testing

  • python -m pytest acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_issue_handler.py

Vijay Soni and others added 2 commits December 23, 2025 21:08
Copy link
Contributor

@jamshale jamshale left a comment

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses issue #3845 by preventing auto-store failures from incorrectly moving v2.0 credential exchanges to the done state. The fix differentiates between recoverable storage errors (which leave the credential in credential-received state for manual retry) and unrecoverable errors (which abandon the exchange).

Key changes:

  • Added a cred_store_succeeded flag to track successful credential storage
  • Separated StorageError handling to allow retries by keeping credentials in credential-received state
  • Only send credential acknowledgment when storage actually succeeds

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
acapy_agent/protocols/issue_credential/v2_0/handlers/cred_issue_handler.py Implements differentiated error handling for auto-store failures, with StorageError allowing retry and other errors triggering abandonment
acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_issue_handler.py Updates tests to verify error handling behavior with proper mock setup and assertions for both error paths

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +78 to +81
mock_cred_ex = mock.MagicMock(
save_error_state=mock.CoroutineMock(),
save=mock.CoroutineMock(),
)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The mock object mock_cred_ex needs to include the error_msg attribute because the handler code sets cred_ex_record.error_msg = err.roll_up when a StorageError occurs. Without this attribute in the mock, the test may not properly validate that the error message is being set correctly on the credential exchange record.

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +113
mock_cred_ex = mock.MagicMock(
save_error_state=mock.CoroutineMock(),
save=mock.CoroutineMock(),
)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The mock object mock_cred_ex needs to include the error_msg attribute because the handler code sets cred_ex_record.error_msg = err.roll_up when a StorageError occurs. Without this attribute in the mock, the test may not properly validate that the error message is being set correctly on the credential exchange record.

Copilot uses AI. Check for mistakes.
Comment on lines 84 to 86
store_credential=mock.CoroutineMock(
side_effect=[
test_module.IndyHolderError,
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The StorageError() instantiation should provide a message or have a mocked roll_up property. In the handler code at line 81, err.roll_up is accessed when a StorageError occurs. Without a proper message or mocked roll_up attribute, this will cause the roll_up property to return "StorageError." which may not provide meaningful testing of the error message handling. Consider passing a message like StorageError("Database connection failed") to make the test more realistic.

Copilot uses AI. Check for mistakes.
Comment on lines 116 to 118
store_credential=mock.CoroutineMock(
side_effect=[
test_module.AnonCredsHolderError,
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

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

The StorageError() instantiation should provide a message or have a mocked roll_up property. In the handler code at line 81, err.roll_up is accessed when a StorageError occurs. Without a proper message or mocked roll_up attribute, this will cause the roll_up property to return "StorageError." which may not provide meaningful testing of the error message handling. Consider passing a message like StorageError("Database connection failed") to make the test more realistic.

Copilot uses AI. Check for mistakes.
@jamshale jamshale self-requested a review January 6, 2026 17:15
@jamshale
Copy link
Contributor

jamshale commented Jan 6, 2026

There is some co-pilot suggestions. If you could go over them quickly and decide if they are worth addressing, please. The fix looks good to me.

Copy link
Member

@esune esune left a comment

Choose a reason for hiding this comment

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

I resolved a couple of the Copilot comments as I think they were not necessary (asserting to check the mock error message was set in the object). I echo @jamshale for the others, change look otherwise good.

@sonarqubecloud
Copy link

@swcurran swcurran merged commit d462392 into openwallet-foundation:main Jan 13, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants