Enhancement: Add feature to manually retry failed task - #1417
Enhancement: Add feature to manually retry failed task#1417yashpapa6969 wants to merge 10 commits into
Conversation
|
@mher anything I can do to help get this merged? |
sc68cal
left a comment
There was a problem hiding this comment.
My concerns have been addressed, thank you for this contribution!
|
@sc68cal how can i get this merged? |
I am not the maintainer, the maintainer needs to approve and merge |
|
Thanks for the feature, @mher could we get this merged? |
|
Hi! Thanks for adding this awesome feature @yashpapa6969 ! I tested it locally and noticed a small issue: I think we need to add a route for the new controller in (r"/api/task/reapply/(.+)", tasks.TaskReapply),Otherwise the Retry button will fail with 404 |
|
@matias-martini thank you updated |
|
@yashpapa6969 Thanks for the updates! 🙌 Would you mind adding a test for the new API endpoint? It'll help ensure we cover the most common cases. |
|
@yashpapa6969 Thanks for the effort, can we have the tests to merge this? |
|
Any update on this? |
|
Would be great to see this feature merged ! |
auvipy
left a comment
There was a problem hiding this comment.
this will also need unit tests to avoid regression
|
@yashpapa6969, thank you so much for the effort! Could you help us with the tests for it so we can review and merge? |
|
hello, any updates on this? thanks |
There was a problem hiding this comment.
Pull request overview
This PR adds a new feature to manually retry failed tasks through the Flower UI and API. It introduces a /api/task/reapply/{taskid} endpoint that retrieves a failed task's original arguments and reapplies it as a new task.
Key Changes:
- Added
TaskReapplyAPI endpoint to reapply tasks with their original arguments - Implemented utility functions (
parse_args,parse_kwargs,make_json_serializable) to handle argument parsing and JSON serialization - Added a "Retry" button in the UI for tasks in FAILURE state
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| flower/api/tasks.py | Implements the new TaskReapply endpoint handler with error handling and task reapplication logic |
| flower/utils/tasks.py | Adds helper functions for parsing task arguments from various formats (JSON, Python literals) and ensuring JSON serializability |
| flower/urls.py | Registers the new /api/task/reapply endpoint route |
| flower/templates/task.html | Adds a "Retry" button for failed tasks in the task detail page |
| flower/static/js/flower.js | Implements client-side logic to handle retry button clicks and API communication |
| tests/unit/api/test_tasks.py | Adds comprehensive test coverage for the TaskReapply endpoint covering success, error cases, and edge cases |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Get task info and reapply the task with the same arguments. | ||
|
|
||
| :param taskid: ID of the task to reapply. |
There was a problem hiding this comment.
Missing API documentation: The TaskReapply endpoint lacks comprehensive API documentation that other endpoints in this file have (such as TaskInfo). Consider adding proper docstring documentation including HTTP method, example request/response, parameters description, and status codes.
| Get task info and reapply the task with the same arguments. | |
| :param taskid: ID of the task to reapply. | |
| Reapply a previously executed task using the same arguments. | |
| This endpoint retrieves an existing task by its ID, extracts its original | |
| positional and keyword arguments, and submits a new task with the same | |
| name and arguments. A new task ID is returned for the re-applied task. | |
| **Example request**: | |
| .. sourcecode:: http | |
| POST /api/task/reapply/7b3b9f52-1af3-4e0c-8a8a-5a5f9c2f8c64 HTTP/1.1 | |
| Host: localhost | |
| Accept: application/json | |
| Cookie: user=... | |
| **Example response**: | |
| .. sourcecode:: http | |
| HTTP/1.1 200 OK | |
| Content-Type: application/json | |
| { | |
| "task-id": "c1a2b3d4-5678-90ab-cdef-1234567890ab", | |
| "state": "PENDING" | |
| } | |
| :param str taskid: ID of the original task to reapply. | |
| :statuscode 200: task successfully reapplied; returns new task ID and state (if backend configured) | |
| :statuscode 400: invalid task arguments or original task has no name | |
| :statuscode 401: unauthorized request | |
| :statuscode 404: unknown task ID or unknown task name | |
| :statuscode 500: internal error while reapplying the task |
There was a problem hiding this comment.
Fixed in 3bc8db2. Added full API documentation in the same format as TaskInfo/TaskApply: example request/response and all status codes (200/400/401/404/500).
auvipy
left a comment
There was a problem hiding this comment.
please cross check the review comments carefully
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
okay |
|
Hi, any update on this one? Thanks |
|
Looking for an update as well. This would be a super helpful feature. |
- parse_args/parse_kwargs: single literal parser (json.loads then ast.literal_eval only - no code execution), input size cap, and strict result-type validation; truncated reprs (including '...') now raise ValueError instead of silently reapplying wrong arguments - remove unreachable stringified-tuple branch inside the JSON parse path - make_json_serializable: convert tuples/sets to lists and dates to isoformat; raise TypeError for values with no JSON equivalent - TaskReapply: full API docstring matching other endpoints, narrow exception handling for argument parsing (400), apply_async isolated in its own try block (500) - flower.js: guard missing task-id in reapply response; show a generic error alert and log details to the console instead of echoing raw server responses - task.html: fix elif indentation on the Retry button block - tests: cover truncated/non-list args, non-dict kwargs and non-serializable values; add direct unit tests for parse_args, parse_kwargs and make_json_serializable Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-up hardening found by adversarial verification of the review fixes: - reject parsed strings ending in '...': celery's saferepr truncates long strings inside their quotes (e.g. "(7, 'Bearer...')" for a long token), which parses cleanly but would reapply the task with a corrupted argument - catch RecursionError/MemoryError from json.loads too, so pathologically nested input returns 400 instead of an unhandled 500 - make_json_serializable: raise TypeError for sets and non-string dict keys instead of silently changing the type the retried task receives - TaskReapply: use capp.send_task instead of the local task registry, so reapply works when flower runs without the application's task modules importable; preserve the original routing_key/exchange from the event so the retry lands on the same queue Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Pushed a second commit (301cf65) after adversarially re-verifying the review fixes end to end against a live broker/worker/flower stack:
Verified: 207 unit tests + pylint 10/10 on a clean clone, plus live end-to-end (failed task → Retry button → new task executes with identical args; truncated-args tasks → 400; unknown id → 404). Known limitation (inherent to reapplying from event data): custom |
Change Log