from getstream.exceptions import StreamTaskException, StreamTransportException
response = client.delete_channels(cids=["messaging:c1", "messaging:c2"], hard_delete=True)
task_id = response.task_id
try:
result = client.wait_for_task(task_id)
print("task completed:", result)
except StreamTaskException as e:
print(f"task {e.task_id} failed: {e.description}")
except StreamTransportException as e:
if e.error_type == "timeout":
# wait elapsed; task may still be running on the server
...Polling Async Tasks
Some operations on Stream's API take longer than a single HTTP response can wait for. Hard-delete-channels, channel export, user export, and similar batch jobs return a task_id immediately and run in the background. To get the result, poll the task status endpoint.
The SDK ships a helper that polls for you and surfaces the outcome as either a typed result (when the task completes) or a typed exception (when it fails or the wait elapses).
Waiting on a task
import io.getstream.exceptions.StreamTaskException;
import io.getstream.exceptions.StreamTransportException;
try {
var result = client.waitForTask(taskId);
// task completed
} catch (StreamTaskException e) {
System.err.println("task " + e.getTaskId() + " failed: " + e.getDescription());
} catch (StreamTransportException e) {
if ("timeout".equals(e.getErrorType())) {
// wait elapsed; task may still be running on the server
}
}Behavior
| Task outcome | Helper's reaction |
|---|---|
status: "completed" | Returns the task result payload. |
status: "failed" | Raises the SDK's task exception with task_id, error_type, description, stack_trace, version. |
| Deadline exceeded | Raises the SDK's transport exception with error_type = "timeout". The task may still be running on the server. |
Java exposes the server-side stack trace via getStackTraceText(), not getStackTrace(). The latter is reserved for the JVM's own Throwable.getStackTrace() (StackTraceElement[]).
Defaults
| Parameter | Default |
|---|---|
| Poll interval | 1 second |
| Wait timeout | 60 seconds |
Override either knob if your task is expected to run longer, or if you want a tighter loop.
client.waitForTask(taskId, Duration.ofSeconds(5), Duration.ofMinutes(10));Polling manually
If you need a custom polling loop (back-off, progress logging, external cancellation), call getTask yourself. The helper is a convenience over the same endpoint.
import time
while True:
response = client.get_task(task_id)
if response.data.status in ("completed", "failed"):
break
time.sleep(1.0)The Async variant in your SDK (e.g. Python's AsyncStream.wait_for_task, .NET's WaitForTaskAsync) is non-blocking and accepts the same parameters.