Comprehensive error handling system for module loading failures, dependency issues, and build-time errors in RequireJS applications.
RequireJS provides detailed error information for different failure scenarios.
/**
* RequireJS error object structure
*/
interface RequireError extends Error {
/** Type of error that occurred */
requireType: "timeout" | "nodefine" | "scripterror" | "mismatch" | "notloaded";
/** Array of module names involved in error */
requireModules: string[];
/** Original error if available */
originalError?: Error;
/** Context name where error occurred */
contextName?: string;
/** Module name that caused the error */
moduleName?: string;
/** Dependency tree leading to error */
moduleTree?: string[];
}
/**
* Error type definitions
*/
interface ErrorTypes {
/** Module loading timeout */
timeout: "Module loading exceeded waitSeconds timeout";
/** Script loaded but no define() called */
nodefine: "Script file loaded but no module defined";
/** Network error loading script */
scripterror: "Script loading error (404, network, syntax)";
/** Module name mismatch */
mismatch: "Module name does not match expected name";
/** Module not loaded when accessed synchronously */
notloaded: "Module not loaded for synchronous require";
}Usage Examples:
// Error handling in require calls
require(['problematic-module'],
function(module) {
// Success callback
console.log('Module loaded successfully');
},
function(err) {
// Error callback
console.log('Error type:', err.requireType);
console.log('Failed modules:', err.requireModules);
console.log('Context:', err.contextName);
switch(err.requireType) {
case 'timeout':
console.error('Module loading timed out');
break;
case 'nodefine':
console.error('Script loaded but no module defined');
break;
case 'scripterror':
console.error('Network or syntax error loading script');
break;
}
}
);Set up application-wide error handling for RequireJS failures.
/**
* Global error handler
* @param err - RequireJS error object
*/
function requirejs.onError(err: RequireError): void;
/**
* Error handler configuration
*/
interface ErrorHandlerConfig {
/** Log errors to console */
logErrors?: boolean;
/** Report errors to external service */
reportErrors?: boolean;
/** Fallback module loading */
fallbackLoading?: boolean;
/** Retry failed loads */
retryLoading?: boolean;
}Usage Examples:
// Basic global error handler
requirejs.onError = function(err) {
console.error('RequireJS Error:', err);
// Log detailed information
console.group('Error Details:');
console.log('Type:', err.requireType);
console.log('Modules:', err.requireModules);
console.log('Message:', err.message);
if (err.originalError) {
console.log('Original Error:', err.originalError);
}
console.groupEnd();
};
// Advanced error handler with reporting
requirejs.onError = function(err) {
// Log locally
console.error('RequireJS Error:', err.requireType, err.requireModules);
// Report to error tracking service
if (window.errorTracker) {
window.errorTracker.report({
type: 'requirejs_error',
errorType: err.requireType,
modules: err.requireModules,
message: err.message,
stack: err.stack,
url: window.location.href,
userAgent: navigator.userAgent,
timestamp: new Date().toISOString()
});
}
// Try fallback loading for certain errors
if (err.requireType === 'scripterror' && err.requireModules.length === 1) {
var failedModule = err.requireModules[0];
// Try CDN fallback
if (window.fallbackPaths && window.fallbackPaths[failedModule]) {
console.log('Attempting fallback for:', failedModule);
requirejs.undef(failedModule);
require.config({
paths: {
[failedModule]: window.fallbackPaths[failedModule]
}
});
// Retry loading
require([failedModule], function() {
console.log('Fallback successful for:', failedModule);
});
}
}
};Handle errors for individual module loads with custom recovery strategies.
/**
* Module loading with error handling
*/
interface ModuleErrorHandling {
/** Success callback */
success: (module: any) => void;
/** Error callback */
error: (err: RequireError) => void;
/** Recovery strategies */
recovery?: {
retry?: boolean;
fallback?: string | string[];
default?: any;
};
}Usage Examples:
// Error handling with retry logic
function loadModuleWithRetry(moduleName, maxRetries = 3) {
let attempts = 0;
function attemptLoad() {
attempts++;
require([moduleName],
function(module) {
console.log(`Module ${moduleName} loaded on attempt ${attempts}`);
return module;
},
function(err) {
console.error(`Attempt ${attempts} failed for ${moduleName}:`, err.requireType);
if (attempts < maxRetries) {
console.log(`Retrying ${moduleName} (${attempts}/${maxRetries})...`);
// Clean up failed module
requirejs.undef(moduleName);
// Retry after delay
setTimeout(attemptLoad, 1000 * attempts);
} else {
console.error(`Failed to load ${moduleName} after ${maxRetries} attempts`);
}
}
);
}
attemptLoad();
}
// Error handling with fallback modules
function loadWithFallback(primary, fallback, defaultValue) {
require([primary],
function(module) {
console.log('Primary module loaded:', primary);
return module;
},
function(primaryErr) {
console.warn('Primary module failed, trying fallback:', fallback);
require([fallback],
function(module) {
console.log('Fallback module loaded:', fallback);
return module;
},
function(fallbackErr) {
console.error('Both primary and fallback failed');
console.error('Primary error:', primaryErr);
console.error('Fallback error:', fallbackErr);
// Use default value
return defaultValue;
}
);
}
);
}
// Usage
loadModuleWithRetry('flaky-network-module');
loadWithFallback('advanced-feature', 'basic-feature', { disabled: true });Handle errors during build optimization process.
/**
* Build error types
*/
interface BuildError extends Error {
/** Build error type */
buildType: "dependency" | "minification" | "file" | "plugin" | "circular";
/** Files involved in error */
files?: string[];
/** Modules involved in error */
modules?: string[];
/** Build step where error occurred */
buildStep?: string;
}
/**
* Build error handling configuration
*/
interface BuildErrorConfig {
/** Continue build on non-critical errors */
continueOnError?: boolean;
/** Log build errors to file */
logFile?: string;
/** Fail build on specific error types */
failOn?: string[];
/** Ignore specific error types */
ignore?: string[];
}Usage Examples:
// Build configuration with error handling
({
baseUrl: 'src',
name: 'main',
out: 'dist/main.js',
// Error handling options
throwWhen: {
// Fail build on these errors
optimize: false // Don't fail on minification errors
},
// Build callback for handling errors
onBuildRead: function(moduleName, path, contents) {
try {
// Process file contents
return contents;
} catch (e) {
console.error(`Error processing ${moduleName}:`, e);
// Return original contents on error
return contents;
}
},
onBuildWrite: function(moduleName, path, contents) {
try {
// Validate output
if (contents.length === 0) {
throw new Error(`Empty output for ${moduleName}`);
}
return contents;
} catch (e) {
console.error(`Build write error for ${moduleName}:`, e);
throw e; // Re-throw to fail build
}
}
})Tools and techniques for diagnosing RequireJS loading issues.
/**
* Debugging utilities
*/
interface DebuggingUtils {
/** Check if module is defined */
defined: (moduleName: string) => boolean;
/** Check if module is specified */
specified: (moduleName: string) => boolean;
/** Get current context state */
getContext: (contextName?: string) => Context;
/** List all defined modules */
listModules: () => string[];
/** Get dependency graph */
getDependencies: (moduleName: string) => string[];
}
interface Context {
/** Loaded modules */
defined: { [key: string]: any };
/** Modules being loaded */
waiting: { [key: string]: boolean };
/** URLs that have been fetched */
urlFetched: { [key: string]: boolean };
/** Module dependency map */
depMaps: { [key: string]: any[] };
}Usage Examples:
// Debugging utilities
function debugRequireJS() {
console.group('RequireJS Debug Information');
// Check context state
var ctx = requirejs.s.contexts._;
console.log('Defined modules:', Object.keys(ctx.defined));
console.log('Waiting modules:', Object.keys(ctx.waiting));
console.log('Fetched URLs:', Object.keys(ctx.urlFetched));
// Check specific modules
var problematicModules = ['module1', 'module2', 'module3'];
problematicModules.forEach(function(mod) {
console.log(`${mod}:`);
console.log(` - defined: ${requirejs.defined(mod)}`);
console.log(` - specified: ${requirejs.specified(mod)}`);
});
console.groupEnd();
}
// Error recovery helper
function recoverFromError(err) {
if (err.requireType === 'timeout') {
console.log('Attempting to recover from timeout...');
// Increase timeout
requirejs.config({
waitSeconds: 30
});
// Retry failed modules
err.requireModules.forEach(function(mod) {
requirejs.undef(mod);
});
require(err.requireModules, function() {
console.log('Recovery successful');
});
}
}
// Module health check
function checkModuleHealth(moduleName) {
return new Promise(function(resolve, reject) {
if (requirejs.defined(moduleName)) {
resolve({ status: 'loaded', module: require(moduleName) });
return;
}
if (requirejs.specified(moduleName)) {
resolve({ status: 'loading' });
return;
}
// Try to load
require([moduleName],
function(module) {
resolve({ status: 'loaded', module: module });
},
function(err) {
reject({ status: 'failed', error: err });
}
);
});
}
// Usage
debugRequireJS();
checkModuleHealth('my-module').then(console.log).catch(console.error);Typical error situations and their solutions.
/**
* Common error patterns and solutions
*/
interface CommonErrors {
/** Circular dependency detection */
circular: {
detect: () => string[][];
resolve: (modules: string[]) => void;
};
/** Missing script files */
missing: {
paths: string[];
suggestions: string[];
};
/** Configuration problems */
config: {
issues: string[];
fixes: string[];
};
}Usage Examples:
// Common error scenarios and solutions
// 1. Timeout Error Solution
require.config({
waitSeconds: 30, // Increase from default 7 seconds
paths: {
'slow-loading-lib': [
'https://cdn1.example.com/lib', // Primary CDN
'https://cdn2.example.com/lib', // Fallback CDN
'local/lib' // Local fallback
]
}
});
// 2. Script Error with Fallback
require(['flaky-module'],
function(module) {
// Success
},
function(err) {
if (err.requireType === 'scripterror') {
// Try alternative path
require.config({
paths: {
'flaky-module': 'backup/flaky-module'
}
});
require(['flaky-module'], function(module) {
console.log('Loaded from backup location');
});
}
}
);
// 3. No Define Error Solution
require(['legacy-script'],
function() {
// Access global variable created by script
return window.LegacyLibrary;
},
function(err) {
if (err.requireType === 'nodefine') {
// Configure as shim
require.config({
shim: {
'legacy-script': {
exports: 'LegacyLibrary'
}
}
});
require(['legacy-script'], function(lib) {
console.log('Legacy library loaded via shim');
});
}
}
);
// 4. Circular Dependency Resolution
function detectCircularDependencies() {
var ctx = requirejs.s.contexts._;
var circular = [];
// Simple circular dependency detection
for (var modId in ctx.depMaps) {
var deps = ctx.depMaps[modId];
if (deps && deps.some(dep =>
ctx.depMaps[dep.id] &&
ctx.depMaps[dep.id].some(d => d.id === modId)
)) {
circular.push([modId, deps.map(d => d.id)]);
}
}
return circular;
}// Error handling types
interface ErrorHandler {
(err: RequireError): void;
}
interface ErrorRecoveryStrategy {
retry: boolean;
maxRetries: number;
fallbackPaths: string[];
defaultValue: any;
onRetry: (attempt: number) => void;
onFallback: (path: string) => void;
onDefault: () => void;
}
interface ErrorReporting {
service: string;
apiKey: string;
metadata: { [key: string]: any };
filter: (err: RequireError) => boolean;
}
// Build error types
interface BuildErrorSummary {
totalErrors: number;
errorsByType: { [type: string]: number };
failedModules: string[];
warnings: string[];
buildTime: number;
}
interface ErrorContext {
requirejs: {
version: string;
context: string;
config: any;
};
browser: {
userAgent: string;
url: string;
referrer: string;
};
timing: {
pageLoad: number;
errorTime: number;
};
}