Handle Python SDK errors without duplicating solves
A connection timeout doesn't prove that task creation failed. Keep the original task inputs and requestId; recover that request before creating another solve.
On this page
Catch task failures separately from HTTP errors
The synchronous Python SDK's solve method creates a task once and polls until it is ready or raises an error. Catch the specific exceptions before SolvethreeError so you can distinguish a failed solve from an interrupted HTTP request.
Set SOLVETHREE_API_KEY and SOLVETHREE_PROXY, then replace the example hostname and action with your target's values. The site needs an active workspace profile before it can be solved.
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: the task reached terminalfailedstatus. Inspecterror.task_idanderror.error_code; don't continue polling that task.ApiError: an HTTP request failed. Inspecterror.statusanderror.retry_after, which is measured in seconds. This isn't the same as a terminal task failure.SolvethreeError: retainerror.request_idanderror.task_idfor explicit recovery. Use whichever IDs are available rather than assuming creation never happened.
The example prints recovery information, but it doesn't persist it or perform recovery. In an integration that must survive a process restart, save the original task inputs and request ID before calling solve, then retain any returned task ID. Protect stored inputs that contain proxy credentials.
Resume by task ID; recover creation by request ID
- 1.
If you have a task_id, resume get_task
Retrieve that task instead of calling
solveagain.get_taskaccepts the task ID and await_msargument; its default wait is 15000 milliseconds. Continue while status ispendingorsolving. Use the solution only when status isready, and stop onfailed. - 2.
If creation was interrupted before you received a task ID, replay create_task
Send the identical task inputs with the same
requestId, using the recoveredrequest_idwhen needed. Reusing that ID with the same request returns the existing task; changing the inputs conflicts. Once you have its task ID, continue withget_task. - 3.
Don't generate another ID during recovery
The example generates its UUID before calling
solve. Keep that value when recovering; don't rerun task construction and accidentally replace it. A new ID represents a separate request, not a retry of the interrupted one.
The SDK generates a requestId if you omit it, exposes recovery IDs in errors, and never automatically retries task creation. During solve, it honors Retry-After for temporary polling failures within the solve deadline. If the call still raises, use the saved IDs to resume rather than starting another solve.
Recovery isn't a reason to repeat invalid requests
For ApiError, inspect the HTTP error before deciding to replay anything. Recovering interrupted creation is appropriate when the outcome is uncertain; blindly resending unchanged invalid inputs isn't.
For TaskFailedError, the task is finished. A retrieved failed task contains errorCode and error; the Python exception exposes the code as error.error_code. Use that information to decide what needs changing. For example, site-unreachable calls for investigating target reachability, not assuming the account lacks credit. Failed solves are refunded.
Sources and API reference
Run your first task.
Start with $5 in workspace credit.