解答処理を重複させずにPython SDKのエラーを処理する

著者:solvethree読了時間:1分

接続タイムアウトは、タスク作成が失敗した証拠ではありません。元のタスク入力と requestId を保持し、別の解決処理を作成する前に、そのリクエストを復旧してください。

このページの内容

タスクの失敗を HTTP エラーと分けて捕捉する

同期版 Python SDK の solve メソッドは、タスクを 1 回だけ作成し、準備完了になるかエラーが発生するまでポーリングします。解決処理の失敗と HTTP リクエストの中断を区別できるよう、SolvethreeError より先に個別の例外を捕捉してください。

SOLVETHREE_API_KEY と SOLVETHREE_PROXY を設定し、例のホスト名とアクションを対象の値に置き換えてください。解決処理を行うには、対象サイトに有効なワークスペースプロファイルが必要です。

Python · 失敗を区別し、中断したリクエストを復旧
import os
import uuid
from solvethree import Solvethree, ApiError, TaskFailedError, SolvethreeError

client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
task = {"site": "accounts.example.com", "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"], "requestId": str(uuid.uuid4())}
try:
    result = client.solve(task, timeout=180)
    print("Ready task:", result["id"])
    # Submit result["solution"] privately through the target application.
except TaskFailedError as error:
    print("Failed task:", error.task_id, "code:", error.error_code)
    # This task is terminal. Inspect it before starting different work.
except ApiError as error:
    print("HTTP status:", error.status, "retry delay:", error.retry_after)
    print("Recovery IDs:", error.request_id, error.task_id)
    # A known task_id means resume get_task; otherwise replay the exact task
    # with error.request_id. Do not generate a new logical request to recover it.
except SolvethreeError as error:
    print("Recovery IDs:", error.request_id, error.task_id)
    # Save these IDs and the original task inputs for explicit recovery.
  • TaskFailedError:タスクが終端状態の failed に達しました。error.task_id と error.error_code を確認し、そのタスクのポーリングは続けないでください。
  • ApiError:HTTP リクエストが失敗しました。error.status と、秒単位の error.retry_after を確認してください。これはタスクの終端的な失敗とは異なります。
  • SolvethreeError:明示的に復旧するために、error.request_id と error.task_id を保持してください。作成されなかったと決めつけず、利用可能な ID を使ってください。

この例は復旧情報を出力しますが、永続化も復旧処理も行いません。プロセスの再起動後も継続する必要がある連携では、solve を呼び出す前に元のタスク入力とリクエスト ID を保存し、返されたタスク ID も保持してください。プロキシの認証情報を含む保存済みの入力は保護してください。

タスク ID で再開し、リクエスト ID で作成処理を復旧する

  1. 1.

    task_id がある場合は get_task を再開する

    solve を再度呼び出すのではなく、そのタスクを取得してください。get_task はタスク ID と wait_ms 引数を受け取り、デフォルトの待機時間は 15000 ミリ秒です。ステータスが pending または solving の間は続けます。ソリューションを使用するのはステータスが ready の場合だけにし、failed になったら停止してください。

  2. 2.

    タスク ID を受け取る前に作成処理が中断された場合は create_task を再送信する

    同じ requestId と完全に同じタスク入力を送信し、必要に応じて復旧情報から得た request_id を使用してください。同じ ID と同じリクエストを再利用すると既存のタスクが返されますが、入力を変更すると競合が発生します。タスク ID を取得したら、get_task で処理を続けてください。

  3. 3.

    復旧時に別の ID を生成しない

    この例では、solve を呼び出す前に UUID を生成します。復旧時はその値を保持し、タスクの構築処理を再実行して誤って置き換えないでください。新しい ID は別のリクエストを表し、中断されたリクエストの再試行にはなりません。

SDK は、requestId を省略すると生成し、エラーで復旧用 ID を公開しますが、タスク作成を自動で再試行することはありません。solve の実行中は、一時的なポーリングの失敗に対して、解決処理の期限内で Retry-After に従います。それでも呼び出しで例外が発生した場合は、別の解決処理を開始せずに、保存した ID を使って再開してください。

復旧を理由に無効なリクエストを繰り返さない

ApiError の場合は、何かを再送信するか判断する前に HTTP エラーを確認してください。結果が不明な場合に中断された作成処理を復旧するのは適切ですが、無効な入力を変更せずに無条件で再送信するのは適切ではありません。

TaskFailedError の場合、タスクは終了しています。取得した失敗タスクには errorCode と error が含まれ、Python の例外ではコードが error.error_code として公開されます。この情報を使って、何を変更する必要があるか判断してください。たとえば site-unreachable の場合は、アカウントのクレジット不足と決めつけるのではなく、対象への到達性を調査する必要があります。失敗した解決処理の料金は返金されます。

最初のタスクを実行しましょう。

$5のワークスペースクレジットで始められます。

ワークスペースを作成
解答処理を重複させずにPython SDKのエラーを処理する · solvethree