Common errors, their causes, and solutions for plugin development.
Hook Errors
HookError
Message: Hook {hook_name} failed in plugin {plugin_name}: {details}
Cause: A hook implementation raised an exception during execution.
Solution:
# Wrong - letting exceptions propagate
def dvp_before_content_create(self, ctx, content, metadata=None):
result = external_api.call() # May raise
return content
# Right - handle exceptions gracefully
def dvp_before_content_create(self, ctx, content, metadata=None):
try:
result = external_api.call()
return content.with_metadata({"enriched": result})
except ExternalAPIError as e:
self.logger.warning(f"API call failed: {e}")
return content # Return original, don't block pipeline
Filter Hook Returns None
Message: Hook {hook_name} returned None but filter hooks must return a value
Cause: A filter hook returned None instead of the modified value.
Solution:
# Wrong - no return statement
def dvp_before_content_create(self, ctx, content, metadata=None):
content["validated"] = True
# Missing return!
# Right - always return the value
def dvp_before_content_create(self, ctx, content, metadata=None):
content["validated"] = True
return content # Must return for filter hooks
Plugin Lifecycle Errors
PluginInitializationError
Message: Plugin {name} failed to initialize: {details}
Cause: Exception raised during plugin.initialize().
Solution:
class MyPlugin(Plugin):
def initialize(self) -> None:
super().initialize() # Always call super first
# Wrap risky operations
try:
self._client = ExternalClient(self._get_config())
except ConnectionError as e:
self.logger.error(f"Failed to connect: {e}")
raise PluginInitializationError(
f"Cannot connect to external service: {e}",
plugin_name=self.name,
)
PluginDependencyError
Message: Plugin {name} requires {dependency} but it is not available
Solution:
# Check your plugin's dependencies list
class MyPlugin(Plugin):
name = "my-plugin"
dependencies = ["other-plugin"] # Must be installed and enabled
# Ensure dependency is registered before your plugin
registry.register(OtherPlugin())
registry.register(MyPlugin())
registry.enable("other-plugin") # Enable dependency first
registry.enable("my-plugin")
Messaging Errors
MessageTimeoutError
Message: Request to {target} timed out after {timeout}ms
Solution:
try:
response = await bus.request(
sender="my-plugin",
target="slow-plugin",
message_type="query",
payload={"question": "complex query"},
timeout_ms=10000, # Increase timeout
)
except MessageTimeoutError:
self.logger.warning("Slow plugin timed out, using fallback")
response = self._get_fallback_response()
Debugging Techniques
Enable Debug Logging
import logging
logging.getLogger("dvp_cms.plugins").setLevel(logging.DEBUG)
Validate Plugin Registration
from dvp_cms.plugins.hookspec import get_implemented_hooks, validate_hooks
# Check what hooks your plugin implements
hooks = get_implemented_hooks(my_plugin)
print(f"Implemented hooks: {hooks}")
# Validate hook signatures
errors = validate_hooks(my_plugin)
if errors:
print(f"Validation errors: {errors}")
Troubleshooting Checklist
Plugin Not Loading
plugin.jsonexists and is valid JSON- Required fields present:
name,version,main mainpoints to validmodule:ClassName- No Python import errors
Hook Not Called
- Plugin is registered with
registry.register(plugin) - Plugin is enabled with
registry.enable(plugin_name) - Hook method name is correct (e.g.,
dvp_content_created) - Plugin inherits correct protocol (e.g.,
ContentLifecycleHooks)