You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python测试无法断言抛出ClientError异常问题排查

Troubleshooting Your Retry Mechanism Test Failure

Let's break down why your test is failing with "Failed: DID NOT RAISE" and how to fix the client factory call count assertion.

Key Issues to Diagnose

First, the "DID NOT RAISE" error means your ContributionHandler isn't propagating the ClientError after exhausting retries. This usually happens because:

  • Your mock isn't consistently throwing ExpiredToken errors across all attempts
  • The retry logic isn't correctly triggering client reconstruction on ExpiredToken
  • You're not letting the retry loop run until it hits the maximum retry limit

Step-by-Step Fixes

1. Ensure Consistent Mocked Errors

Your test needs to simulate that every call to create_contribution throws an ExpiredToken (a subclass of ClientError). If the mock stops throwing errors after the first retry, the handler will succeed silently instead of raising the expected exception.

Use side_effect on your mock client to repeat the error:

import pytest
from your_module import ContributionHandler, ExpiredToken, ClientError

def test_retry_on_expired_token(mocker):
    # Mock the client's create_contribution to always throw ExpiredToken
    mock_client = mocker.Mock()
    mock_client.create_contribution.side_effect = ExpiredToken("Token expired")
    
    # Mock the client factory to return our faulty client every time
    mock_client_factory = mocker.Mock(return_value=mock_client)
    
    # Initialize handler with 2 retries (so total 3 attempts: 1 initial + 2 retries)
    handler = ContributionHandler(client_factory=mock_client_factory, max_retries=2)
    
    # Verify that after all retries, the final error is raised
    with pytest.raises(ClientError):
        handler.create_contribution(your_args_here)
    
    # Assert the factory was called 3 times (once per attempt)
    assert mock_client_factory.call_count == 3

2. Validate Your Retry Logic

Double-check your ContributionHandler implementation to make sure it:

  • Only retries on ExpiredToken specifically (not all ClientError types)
  • Reconstructs the client on each retry
  • Re-raises the error once retries are exhausted

Example correct retry logic:

class ContributionHandler:
    def __init__(self, client_factory, max_retries=2):
        self.client_factory = client_factory
        self.max_retries = max_retries
        self.client = client_factory()
    
    def create_contribution(self, ...):
        retries = 0
        while True:
            try:
                return self.client.create_contribution(...)
            except ExpiredToken as e:
                if retries >= self.max_retries:
                    # No more retries - propagate the error
                    raise
                # Recreate client and increment retry counter
                self.client = self.client_factory()
                retries += 1
            except ClientError as e:
                # Other client errors don't trigger retries
                raise

3. Match Retry Count to Factory Call Count

If you're asserting 3 factory calls, make sure your max_retries is set to 2 (since initial client creation + 2 retries = 3 total factory invocations). If your handler uses a different retry count, adjust the assertion accordingly.

Common Pitfalls to Avoid

  • Forgetting that the initial client is created in __init__ (so factory calls = 1 + max_retries)
  • Using a mock that only throws the error once (so the retry succeeds on the next attempt)
  • Accidentally catching all ClientError types instead of just ExpiredToken for retries

内容的提问来源于stack exchange,提问作者user12042028

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:29:12