Troubleshooting Guide
This guide helps you solve common CronJS issues and provides solutions for frequent problems.
Common Error Messages
1. Syntax Errors in JavaScript Code
Error Message: SyntaxError: Unexpected token
Causes:
- Missing semicolons or brackets
- Invalid JavaScript syntax
- Typos in code
Solutions:
// ❌ Common syntax errors
console.log('Hello World' // Missing closing parenthesis
const data = await fetch() // Missing semicolon
// ✅ Correct syntax
console.log('Hello World');
const data = await fetch('https://api.example.com');
Prevention:
- Use the code editor’s syntax highlighting
- Test code in small pieces
- Use browser developer tools to validate syntax
2. Timeout Errors
Error Message: Job execution timed out after 60 seconds
Causes:
- Job takes longer than 60-second limit
- Infinite loops or hanging operations
- Slow API responses
Solutions:
// ✅ Add timeout to fetch requests
const controller = new AbortController();
setTimeout(() => controller.abort(), 50000); // 50 seconds
try {
const response = await fetch(apiUrl, {
signal: controller.signal,
});
} catch (error) {
if (error.name === "AbortError") {
console.error("Request timed out");
}
throw error;
}
// ✅ Process data in smaller chunks
async function processInBatches(items, batchSize = 10) {
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
await processBatch(batch);
console.log(`Processed ${i + batch.length}/${items.length} items`);
}
}
Prevention:
- Keep jobs under 50 seconds for safety margin
- Use progress logging to track execution
- Consider upgrading to paid plans for higher timeout limits
3. Dependency Installation Failures
Error Message: npm install failed: Package not found
Causes:
- Misspelled package names
- Private packages not accessible
- Package doesn’t exist on npm
Solutions:
// ✅ Verify package names on npmjs.com
// Common correct package names:
const axios = require("axios"); // Not 'axios-http'
const _ = require("lodash"); // Not 'lodash-utils'
const moment = require("moment"); // Not 'momentjs'
// ✅ Use specific versions if needed
// In dependencies section: [email protected]
Prevention:
- Double-check package names on npmjs.com
- Use exact package names from npm documentation
- Test dependencies in local environment first
4. Authentication Token Expiration
Error Message: Authentication failed: Token expired
Causes:
- Firebase token expired during long-running job
- Network connectivity issues
Solutions:
// ✅ Handle authentication errors gracefully
try {
const response = await fetch(apiUrl, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.status === 401) {
console.error("Authentication failed - token may be expired");
throw new Error("Authentication failed");
}
} catch (error) {
console.error("Request failed:", error.message);
throw error;
}
Prevention:
- Keep job execution under timeout limits
- Handle 401 responses gracefully
- Log out and log back in if issues persist
5. Resource Limit Exceeded
Error Message: Job killed: Memory limit exceeded
Causes:
- Processing large datasets in memory
- Memory leaks in code
- Exceeding 128MB memory limit
Solutions:
// ✅ Process data in streams or chunks
async function processLargeFile(data) {
const chunkSize = 1000;
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize);
// Process chunk
await processChunk(chunk);
// Clear references to help garbage collection
chunk.length = 0;
// Log memory usage
const usage = process.memoryUsage();
console.log(`Memory: ${Math.round(usage.heapUsed / 1024 / 1024)}MB`);
}
}
// ✅ Monitor memory usage
function checkMemoryUsage() {
const usage = process.memoryUsage();
const heapUsedMB = Math.round(usage.heapUsed / 1024 / 1024);
if (heapUsedMB > 100) {
// Alert at 100MB
console.warn(`High memory usage: ${heapUsedMB}MB`);
}
return heapUsedMB;
}
Prevention:
- Monitor memory usage with
process.memoryUsage()
- Process data in chunks instead of loading everything
- Consider upgrading to paid plans for higher limits
Job Execution Issues
Jobs Not Running on Schedule
Symptoms:
- Job shows as enabled but doesn’t execute
- Last execution time doesn’t update
Troubleshooting Steps:
-
Check Job Status:
✓ Verify job is enabled in dashboard ✓ Check cron expression is valid ✓ Confirm last execution time
-
Validate Cron Expression:
# Use the visual cron builder to verify # Common valid patterns: */5 * * * * # Every 5 minutes 0 9 * * * # Daily at 9 AM UTC 0 9 * * 1-5 # Weekdays at 9 AM UTC
-
Test Manually:
- Use “Run Now” button to test job execution
- Check execution logs for errors
- Verify job completes successfully
Jobs Failing Silently
Symptoms:
- Job runs but shows no output
- Exit code is 0 but expected results don’t appear
Debugging Steps:
// ✅ Add comprehensive logging
console.log("Job started at:", new Date().toISOString());
console.log("Environment check:", {
nodeVersion: process.version,
envVars: Object.keys(process.env).filter((key) => key.startsWith("API_")),
});
try {
console.log("Starting main task...");
const result = await performMainTask();
console.log("Task completed:", result);
} catch (error) {
console.error("Task failed:", error);
throw error; // Important: re-throw to mark job as failed
} finally {
console.log("Job finished at:", new Date().toISOString());
}
Environment Variables Not Working
Error Message: Cannot read property of undefined
Common Causes:
// ❌ Environment variable not set
const apiKey = process.env.API_KEY; // undefined
const url = apiKey.toString(); // Error: Cannot read property 'toString' of undefined
// ✅ Always check environment variables
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error("API_KEY environment variable is required");
}
// ✅ Use default values where appropriate
const logLevel = process.env.LOG_LEVEL || "info";
const timeout = parseInt(process.env.TIMEOUT) || 30000;
Solutions:
- Verify variable names match exactly (case-sensitive)
- Check variables are set in job configuration
- Add validation at job start
Network and API Issues
External API Calls Failing
Common Error Messages:
ENOTFOUND: getaddrinfo ENOTFOUND
ECONNREFUSED: Connection refused
Timeout exceeded
Solutions:
// ✅ Robust API calling with retries
async function callExternalAPI(url, options = {}, maxRetries = 3) {
const defaultOptions = {
timeout: 30000,
headers: {
"User-Agent": "CronJS-Job/1.0",
"Content-Type": "application/json",
},
...options,
};
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`API call attempt ${attempt} to: ${url}`);
const controller = new AbortController();
setTimeout(() => controller.abort(), defaultOptions.timeout);
const response = await fetch(url, {
...defaultOptions,
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
console.log("API call successful");
return await response.json();
} catch (error) {
console.error(`Attempt ${attempt} failed:`, error.message);
if (attempt === maxRetries) {
throw new Error(
`All ${maxRetries} API attempts failed: ${error.message}`
);
}
// Exponential backoff
const delay = 1000 * Math.pow(2, attempt - 1);
console.log(`Waiting ${delay}ms before retry...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
// Usage
try {
const data = await callExternalAPI("https://api.example.com/data");
console.log("Data received:", data);
} catch (error) {
console.error("Failed to fetch data:", error.message);
// Handle the failure appropriately
}
DNS Resolution Issues
Solutions:
// ✅ Use IP addresses for critical services (if available)
const apiUrl =
process.env.USE_IP === "true"
? "http://192.168.1.100/api"
: "https://api.example.com";
// ✅ Test DNS resolution
try {
const testResponse = await fetch(
"https://dns.google/resolve?name=api.example.com&type=A"
);
const dnsResult = await testResponse.json();
console.log("DNS resolution:", dnsResult);
} catch (error) {
console.warn("DNS test failed:", error.message);
}
Performance Issues
Slow Job Execution
Diagnostics:
// ✅ Performance profiling
async function profiledTask(taskName, taskFunction) {
const startTime = Date.now();
const startMemory = process.memoryUsage();
console.log(`Starting ${taskName}...`);
try {
const result = await taskFunction();
const endTime = Date.now();
const endMemory = process.memoryUsage();
console.log(`${taskName} completed:`, {
duration: `${endTime - startTime}ms`,
memoryUsed: `${Math.round(
(endMemory.heapUsed - startMemory.heapUsed) / 1024 / 1024
)}MB`,
peakMemory: `${Math.round(endMemory.heapUsed / 1024 / 1024)}MB`,
});
return result;
} catch (error) {
console.error(
`${taskName} failed after ${Date.now() - startTime}ms:`,
error.message
);
throw error;
}
}
// Usage
const data = await profiledTask("Data Fetch", () => fetchData());
const processed = await profiledTask("Data Processing", () =>
processData(data)
);
Optimization Strategies:
// ✅ Parallel processing where possible
async function processItemsInParallel(items, maxConcurrency = 5) {
const results = [];
for (let i = 0; i < items.length; i += maxConcurrency) {
const batch = items.slice(i, i + maxConcurrency);
const batchPromises = batch.map((item) => processItem(item));
const batchResults = await Promise.all(batchPromises);
results.push(...batchResults);
console.log(
`Processed ${Math.min(i + maxConcurrency, items.length)}/${
items.length
} items`
);
}
return results;
}
// ✅ Efficient data processing
function processLargeArray(array) {
// Use array methods that don't create intermediate arrays
return array
.filter((item) => item.isValid)
.map((item) => transformItem(item))
.reduce((acc, item) => {
acc[item.category] = (acc[item.category] || 0) + item.value;
return acc;
}, {});
}
Authentication and Security Issues
Firebase Authentication Problems
Common Issues:
- Session expired during job execution
- Login fails with popup blockers
Solutions:
-
Browser Settings:
- Enable JavaScript and cookies
- Disable popup blockers for app.cronjs.com
- Clear browser cache and cookies
-
Try Incognito Mode:
- Isolates extension conflicts
- Uses fresh session
-
Alternative Auth Methods:
- If Google OAuth fails, try email/password
- If email fails, try Google OAuth
Email Verification Issues
Problem: Didn’t receive verification email
Solutions:
- Check spam/junk folder
- Wait 5-10 minutes for delivery
- Request new verification email
- Try different email address if problem persists
Getting Help and Support
Before Contacting Support
Gather Information:
-
Job Details:
- Job name and ID
- Cron expression
- Last successful execution time
-
Error Information:
- Complete error message
- Execution logs
- Steps to reproduce
-
Environment:
- Browser type and version
- Time zone
- Any recent changes
Contacting Support
Email: [email protected]
Include in Your Message:
- Detailed description of the issue
- Screenshots if relevant
- Job execution logs
- Steps you’ve already tried
Response Time:
- Typical response within 24 hours
- Critical issues prioritized
Self-Help Resources
Documentation:
- Getting Started Guide - Basic setup and first job
- Job Management - Comprehensive job configuration
- Advanced Scheduling - Complex cron patterns
- Monitoring & Logging - Performance tracking
Community:
- Check GitHub discussions
- Search existing documentation
- Review common use cases
Debugging Checklist
When troubleshooting any issue:
✅ Basic Checks
- Job is enabled in dashboard
- Cron expression is valid
- Environment variables are set correctly
- JavaScript syntax is valid
✅ Execution Checks
- Test job with “Run Now” button
- Check execution logs for errors
- Verify job completes within timeout
- Monitor memory usage
✅ Network Checks
- External APIs are accessible
- Network requests have timeouts
- Handle API rate limiting
- Check DNS resolution
✅ Code Quality Checks
- Add comprehensive logging
- Implement error handling
- Validate environment variables
- Use try-catch blocks appropriately
Advanced Debugging
Debug Logging Pattern
// ✅ Comprehensive debug logging
function createLogger(jobName) {
return {
info: (message, data) => {
console.log(
`[${new Date().toISOString()}] [${jobName}] INFO: ${message}`,
data ? JSON.stringify(data) : ""
);
},
error: (message, error) => {
console.error(
`[${new Date().toISOString()}] [${jobName}] ERROR: ${message}`
);
if (error) {
console.error("Error details:", error.message);
console.error("Stack trace:", error.stack);
}
},
warn: (message, data) => {
console.warn(
`[${new Date().toISOString()}] [${jobName}] WARN: ${message}`,
data ? JSON.stringify(data) : ""
);
},
};
}
// Usage
const log = createLogger("data-sync");
log.info("Starting data synchronization");
log.warn("API rate limit approaching", { remainingRequests: 10 });
log.error("Database connection failed", error);
Environment Validation
// ✅ Validate environment at job start
function validateEnvironment() {
const required = ["API_URL", "API_KEY", "DATABASE_URL"];
const missing = required.filter((env) => !process.env[env]);
if (missing.length > 0) {
throw new Error(
`Missing required environment variables: ${missing.join(", ")}`
);
}
console.log("Environment validation passed");
console.log(
"Available environment variables:",
Object.keys(process.env).filter((key) => key.startsWith("API_"))
);
}
// Call at job start
validateEnvironment();
Prevention Best Practices
Code Quality
- Use TypeScript for better error detection
- Implement comprehensive error handling
- Add input validation
- Use linting tools locally
Testing
- Test jobs locally before deploying
- Use “Run Now” to verify functionality
- Test with different data scenarios
- Validate error handling paths
Monitoring
- Add performance logging
- Monitor memory usage
- Set up external health checks
- Track success/failure rates
Security
- Never log sensitive data
- Validate all inputs
- Use environment variables for secrets
- Implement proper error messages
Remember: Most issues can be prevented with good logging, proper error handling, and thorough testing! 🛠️