Debugging Plugins¶
This guide covers techniques and tools for debugging Movian plugins.
Debug Logging¶
Enable Plugin Debug Mode¶
Run Movian with plugin debugging:
Console Logging¶
Use console.log() in your plugin:
Log Levels¶
Common Issues¶
Plugin Not Loading¶
Check:
plugin.jsonis valid JSON- Plugin ID is unique
- File paths are correct
- Movian logs for errors
Debug:
JavaScript Errors¶
Symptoms:
- Plugin crashes
- Functions not working
- Unexpected behavior
Debug:
try {
// Your code
} catch(e) {
console.error("Error:", e.message);
console.error("Stack:", e.stack);
}
HTTP Request Failures¶
Debug HTTP requests (API v2):
var http = require('movian/http');
try {
var response = http.request(url, {
method: 'GET',
debug: true // Enable HTTP debugging
});
console.log("Response:", response.toString());
} catch(e) {
console.error("HTTP Error:", e.message);
}
Page Not Rendering¶
Check:
- Route pattern matches URL
page.loading = falseis set- Items are added correctly
- No JavaScript errors
Debug:
new page.Route("plugin:page", function(page) {
console.log("Route handler called");
page.type = "directory";
console.log("Page type set");
page.appendItem("url", "video", {title: "Test"});
console.log("Item added");
page.loading = false;
console.log("Loading complete");
});
Debugging Techniques¶
Breakpoint Simulation¶
function debugBreakpoint(message) {
console.log("=== BREAKPOINT ===");
console.log(message);
console.log("=================");
}
debugBreakpoint("Before API call");
var result = apiCall();
debugBreakpoint("After API call: " + JSON.stringify(result));
Variable Inspection¶
function inspect(obj, name) {
console.log("=== " + name + " ===");
for (var key in obj) {
console.log(key + ":", obj[key]);
}
console.log("================");
}
inspect(page, "Page Object");
inspect(page.metadata, "Page Metadata");
Timing Analysis¶
var startTime = Date.now();
// Your code here
var endTime = Date.now();
console.log("Execution time:", (endTime - startTime) + "ms");
Network Debugging¶
var http = require('movian/http');
function debugHttpRequest(url, options) {
console.log("HTTP Request:", url);
console.log("Options:", JSON.stringify(options));
var start = Date.now();
try {
var response = http.request(url, options);
var duration = Date.now() - start;
console.log("Response received in", duration + "ms");
console.log("Status:", response.statuscode);
console.log("Headers:", JSON.stringify(response.headers));
return response;
} catch(e) {
console.error("Request failed:", e.message);
throw e;
}
}
Testing Strategies¶
Unit Testing¶
Create test functions:
function testParseData() {
var input = '{"test": "data"}';
var result = parseData(input);
if (result.test === "data") {
console.log("✓ testParseData passed");
} else {
console.error("✗ testParseData failed");
}
}
// Run tests
testParseData();
Integration Testing¶
Test complete workflows:
function testVideoPlayback() {
console.log("Testing video playback...");
// Create test page
new page.Route("test:video", function(page) {
page.type = "directory";
page.appendItem("test:play:1", "video", {
title: "Test Video"
});
page.loading = false;
});
console.log("Test route created");
}
Log Analysis¶
Find Plugin Logs¶
Linux/macOS:
Windows:
Filter Logs¶
Common Error Patterns¶
Syntax Error:
Reference Error:
Type Error:
Best Practices¶
Defensive Programming¶
function safeAccess(obj, path) {
var parts = path.split('.');
var current = obj;
for (var i = 0; i < parts.length; i++) {
if (!current || typeof current !== 'object') {
return undefined;
}
current = current[parts[i]];
}
return current;
}
// Usage
var title = safeAccess(data, 'metadata.title') || 'Unknown';
Error Boundaries¶
function withErrorHandling(fn) {
return function() {
try {
return fn.apply(this, arguments);
} catch(e) {
console.error("Error in", fn.name, ":", e.message);
return null;
}
};
}
// Usage
var safeFunction = withErrorHandling(riskyFunction);
Validation¶
function validateConfig(config) {
var errors = [];
if (!config.apiKey) {
errors.push("Missing apiKey");
}
if (!config.baseUrl) {
errors.push("Missing baseUrl");
}
if (errors.length > 0) {
console.error("Configuration errors:", errors.join(", "));
return false;
}
return true;
}
Tools¶
JSON Validator¶
function isValidJSON(str) {
try {
JSON.parse(str);
return true;
} catch(e) {
console.error("Invalid JSON:", e.message);
return false;
}
}
URL Validator¶
function isValidUrl(url) {
var pattern = /^https?:\/\/.+/;
if (!pattern.test(url)) {
console.error("Invalid URL:", url);
return false;
}
return true;
}
Performance Debugging¶
Memory Usage¶
Monitor object creation:
var objectCount = 0;
function createObject() {
objectCount++;
console.log("Objects created:", objectCount);
return {};
}
Request Optimization¶
var http = require('movian/http');
var requestCache = {};
function cachedRequest(url) {
if (requestCache[url]) {
console.log("Cache hit:", url);
return requestCache[url];
}
console.log("Cache miss:", url);
var response = http.request(url);
requestCache[url] = response;
return response;
}