Skip to content

docs: add async error handling example#2504

Open
vincent067 wants to merge 1 commit intotj:masterfrom
vincent067:add-async-error-handling-example
Open

docs: add async error handling example#2504
vincent067 wants to merge 1 commit intotj:masterfrom
vincent067:add-async-error-handling-example

Conversation

@vincent067
Copy link
Copy Markdown

Hi there! 👋

First off, thanks for maintaining such an awesome library! Commander.js has been my go-to for CLI tools for years.

I noticed that while the README mentions using parseAsync() for async action handlers, there's no complete example showing how to properly handle errors in async contexts. This is a pretty common pain point for developers new to the library.

This PR adds an example that demonstrates:

  • ✅ Proper error handling in async actions (without crashing the CLI)
  • ✅ A simple retry mechanism with the --retry flag
  • ✅ Batch processing with both "continue on error" and "fail fast" modes
  • ✅ Correct exit codes for CI/automation compatibility
  • ✅ Why parseAsync() is important (with .catch() handler)

Example usage:

# Retry failed requests
$ node async-error-handling.js fetch error --retry 3
Retry attempt 1/3...
Retry attempt 2/3...
Retry attempt 3/3...
Error: Failed to fetch data for ID: error

# Batch processing with partial failure
$ node async-error-handling.js batch 1 error 3
✓ 1
✗ error: Failed to fetch data for ID: error
✓ 3

--- Summary ---
Successful: 2
Failed: 1

The example is designed to be:

  • Practical: Shows real-world patterns developers actually need
  • Educational: Well-commented, explaining the "why" not just "how"
  • Runnable: Fully functional code you can execute immediately

I'm open to any feedback or changes you'd prefer! 😊

Thanks for considering!

Add an example demonstrating best practices for handling errors
in async action handlers, including retry logic and batch processing.
@shadowspawn
Copy link
Copy Markdown
Collaborator

there's no complete example showing how to properly handle errors in async contexts. This is a pretty common pain point for developers new to the library.

Have you got any references to new developers having problems?

Most of the problems people have reported in issues are:

  • using asynchronous at all, rather than with Commander
  • not using .exitOverride() when expecting to catch that as an error
  • dangling promises in their own code and program not terminating

However, having an async error example is still a reasonable suggestion! I have different ideas about what to focus on to discuss.

Related past issues: #1144 #1777 #1898 #2325

@vincent067
Copy link
Copy Markdown
Author

Hi @shadowspawn, thanks so much for the thoughtful feedback! 🙏

To be completely honest, I don't have hard references or issue links to back up my claim about "new developers having problems" — that was more based on my own personal experience when I first started using Commander with async actions. I remember being a bit confused about whether to use parse() or parseAsync(), and my script would just silently hang or crash in ways I didn't expect.

Looking at the related issues you linked (#1144, #1777, #1898, #2325), I can see the actual pain points are a bit different from what I focused on here — especially the .exitOverride() situation and dangling promises causing the program to not terminate. That's really good insight, and honestly I hadn't fully appreciated how important the dangling promise issue is until now.

I'd love to revise this example to focus on the things that actually trip people up. Would you be open to me updating the PR to:

  1. Emphasize parseAsync() vs parse() more clearly
  2. Show how .exitOverride() interacts with async actions (if that's useful in an example)
  3. Demonstrate proper promise handling so the program terminates cleanly
  4. Remove or de-emphasize the retry/batch logic since that might be adding noise

I'm totally happy to pivot this in whatever direction you think would be most helpful for the examples directory. Let me know what you'd prefer to see! 😊

@shadowspawn
Copy link
Copy Markdown
Collaborator

Yes please, a pivot. I do think the retry/batch is a bit noisy. Keep the "program" simple and focus on the asynchronous patterns.

I wonder whether should have two examples to show the two styles of outer code? One using try/await main()/catch (in order processing) and one using main().then().catch() (out of order processing). They felt quite different to me when I first used async. The command parser could be the same (copy/paste).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants