Error Handling¶
All exceptions raised by dlight-client inherit from DLightError, making it easy to catch any library error with a single except clause.
Exception hierarchy¶
DLightError
├── DLightConnectionError — could not establish or maintain a TCP connection
│ └── DLightTimeoutError — operation exceeded the timeout threshold
├── DLightCommandError — the device rejected the command
└── DLightResponseError — the device returned an unexpected or malformed response
Exception reference¶
DLightError¶
Base class. Catch this to handle any error from the library without worrying about subtypes.
from dlightclient.exceptions import DLightError
try:
await lamp.turn_on()
except DLightError as e:
print(f"dlight-client error: {e}")
DLightConnectionError¶
Raised when a TCP connection cannot be established to the lamp. Common causes: lamp is off, wrong IP, firewall rule.
from dlightclient.exceptions import DLightConnectionError
try:
await lamp.turn_on()
except DLightConnectionError:
print("Could not reach the lamp — is it powered on?")
Retryable: Yes — this error triggers retries when max_retries > 0.
DLightTimeoutError¶
A subclass of DLightConnectionError. Raised when a connect or read operation exceeds default_timeout.
from dlightclient.exceptions import DLightTimeoutError
client = AsyncDLightClient(default_timeout=2.0)
try:
await lamp.get_state(force_update=True)
except DLightTimeoutError:
print("Lamp did not respond in time")
Retryable: Yes.
DLightCommandError¶
Raised when the lamp responds with a non-SUCCESS status — the command was received but rejected (e.g. value out of range, unknown command).
from dlightclient.exceptions import DLightCommandError
try:
await lamp.set_brightness(150) # out of range
except DLightCommandError as e:
print(f"Command rejected: {e}")
Retryable: No — retrying a rejected command will produce the same result.
DLightResponseError¶
Raised when the device returns a response that cannot be parsed, or when the device echoes the command back (a known hardware quirk that indicates the connection is in a bad state).
Retryable: No — the connection is evicted from the pool; the next command will open a fresh one.
Granular error handling¶
from dlightclient.exceptions import (
DLightTimeoutError,
DLightConnectionError,
DLightCommandError,
DLightResponseError,
DLightError,
)
try:
await lamp.set_color_temperature(3000)
except DLightTimeoutError:
print("Timed out — will retry later")
except DLightConnectionError:
print("Lamp unreachable")
except DLightCommandError as e:
print(f"Bad command: {e}")
except DLightResponseError as e:
print(f"Protocol error: {e}")
except DLightError as e:
print(f"Unexpected library error: {e}")
Logging¶
The library uses the standard logging module under the dlightclient logger hierarchy. By default, no output is produced unless you configure a handler.
import logging
# Show all library debug output
logging.getLogger("dlightclient").setLevel(logging.DEBUG)
logging.basicConfig()
Credential values (Wi-Fi passwords) are masked in all log messages regardless of log level.
Log levels used by the library:
| Level | Examples |
|---|---|
DEBUG |
Connection opened/closed, command sent, retry attempt, pool eviction |
INFO |
Devices discovered |
WARNING |
Retry exhausted, unexpected response |
ERROR |
Unrecoverable protocol error |