CommandNotFoundError Β· custom exception
π Overview
CommandNotFoundError is a Python custom exception class derived from the built-in Exception class. It is designed to signal that an external command or binary could not be located in the directories listed in the PATH environment variable. This provides a clear, semantic error for command-line tools, subprocess invocations, or any scenario where binary presence is required.
CommandNotFoundError to indicate that a mandatory executable (e.g., ffmpeg, docker, git) is missing, allowing graceful error handling and user feedback.
π§ Class Definition
The exception is deliberately minimal, inheriting all standard exception behavior. The docstring clearly states the purpose: βRaised when the binary does not exist in the PATH.β Because no additional attributes are defined, instances behave like a standard exception but with a distinct type for precise except blocks.
| Property | Value |
|---|---|
| Base class | Exception |
| Module | user-defined (typically placed in exceptions.py or command utilities module) |
| String representation | Default Exception representation unless custom __str__ is added. |
| Python version compatibility | Python 3.x+ |
π» Usage Example
Below is a complete example showing how CommandNotFoundError can be raised and caught in a function that checks for binary availability.
from shutil import which
from typing import NoReturn
class CommandNotFoundError(Exception):
"""Raised when the binary does not exist in the PATH."""
pass
def require_command(name: str) -> str:
"""Return command path or raise CommandNotFoundError."""
cmd_path = which(name)
if cmd_path is None:
raise CommandNotFoundError(f"Command '{name}' not found in PATH.")
return cmd_path
# Example usage
try:
path = require_command("ffmpeg")
print(f"β
Found ffmpeg at: {path}")
except CommandNotFoundError as e:
print(f"β Execution failed: {e}")
When the binary is missing, the custom exception propagates a meaningful error that calling code can handle elegantly.
π¦ Attributes & Methods
The CommandNotFoundError class does not define its own constructor or attributes, therefore it inherits all standard methods from the built-in Exception class. The key features are summarized below.
__init__(self, *args)
Constructor inherited from Exception. You can pass an optional error message as an argument (e.g., CommandNotFoundError("git is missing")). The message is stored in the args attribute.
__str__(self)
Returns the string representation of the exception β typically the error message provided during instantiation. If no arguments are given, returns an empty string or the default representation.
args
Tuple of arguments passed to the exception constructor. Useful for retrieving error details in exception handlers.
with_traceback(tb)
Standard method to attach or replace the traceback; commonly used when raising from an exception context.
Because the class is minimal, itβs lightweight and ideal for domain-specific error signaling without overhead.
π³ Inheritance Hierarchy
βββ Exception
βββ CommandNotFoundError custom
This hierarchy means that except Exception will also catch CommandNotFoundError. For precise handling, always catch the specific exception before general ones.
| Class | Description |
|---|---|
BaseException | Base class for all built-in exceptions (includes SystemExit, KeyboardInterrupt). |
Exception | Base class for all non-exit exceptions. User-defined exceptions should typically derive from Exception. |
CommandNotFoundError | Concrete exception indicating a missing binary in PATH. |
β Best Practices & Recommendations
- Provide contextual messages: When raising
CommandNotFoundError, include the command name in the error message to help debugging. - Combine with
shutil.which: Use Python'sshutil.which()to check binary existence before raising the exception. - Keep exception hierarchy clean: If you have multiple command-related errors, consider creating a base
CommandErrorand subclass it, butCommandNotFoundErrorworks perfectly standalone. - Document raised exceptions: In your function docstrings, explicitly mention that
CommandNotFoundErrormay be raised to improve API transparency. - Testing tip: Simulate missing binaries by temporarily modifying PATH in unit tests, and assert that
CommandNotFoundErroris raised correctly.
pass, you can later extend it with additional attributes (e.g., self.command_name) without breaking existing code.
βοΈ Common Scenarios & Handling
| Situation | Recommended Handling |
|---|---|
| Running a subprocess where tool might be missing | Catch CommandNotFoundError and present a friendly error message suggesting installation steps. |
| CLI application with dependency checks | During startup, validate core binaries and raise CommandNotFoundError to halt gracefully. |
| Cross-platform scripts (Windows, Linux, macOS) | The exception is platform-agnostic; use os.environ['PATH'] and which() to maintain portability. |
| Wrap third-party call errors | Convert generic FileNotFoundError or subprocess.CalledProcessError into CommandNotFoundError for consistency. |
π Quick Reference
CommandNotFoundError
raise CommandNotFoundError("msg")
except CommandNotFoundError as e:
class CommandNotFoundError(Exception):
"""Raised when the binary does not exist in the PATH."""
pass