A comprehensive JSON-LD Processor and API implementation in JavaScript for processing Linked Data in JSON format
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Structured error system with detailed error information for debugging and error recovery. JSON-LD operations can encounter various types of errors, and the library provides comprehensive error information to help with debugging and implementing robust error handling strategies.
Custom error class that extends the standard JavaScript Error with additional JSON-LD specific information.
/**
* Custom error class for JSON-LD operations
*/
class JsonLdError extends Error {
/**
* Creates a JSON-LD Error
* @param message - The error message
* @param name - The error type/name
* @param details - Additional error details
*/
constructor(message, name, details);
}Properties:
name (string): Error type identifiermessage (string): Human-readable error messagedetails (object): Additional error-specific informationUsage Examples:
const JsonLdError = require('jsonld/lib/JsonLdError');
// Create custom JSON-LD error
const error = new JsonLdError(
'Invalid context format',
'jsonld.InvalidLocalContext',
{
context: invalidContext,
code: 'invalid local context'
}
);
// Error properties
console.log(error.name); // 'jsonld.InvalidLocalContext'
console.log(error.message); // 'Invalid context format'
console.log(error.details); // { context: ..., code: '...' }Errors that occur during JSON-LD compaction operations.
Error Names:
jsonld.CompactError: General compaction errorsjsonld.InvalidLocalContext: Invalid context provided for compactionCommon Scenarios:
try {
// This will throw because ctx cannot be null
await jsonld.compact(doc, null);
} catch (error) {
if (error.name === 'jsonld.CompactError') {
console.log('Compaction failed:', error.message);
console.log('Error code:', error.details.code); // 'invalid local context'
}
}Errors related to loading remote documents and contexts.
Error Names:
jsonld.LoadDocumentError: Failed to load remote documentjsonld.NullRemoteDocument: Remote document is null or emptyjsonld.InvalidUrl: Invalid URL providedCommon Scenarios:
try {
const doc = await jsonld.expand('http://invalid-url.example');
} catch (error) {
if (error.name === 'jsonld.LoadDocumentError') {
console.log('Failed to load document:', error.details.url);
console.log('Cause:', error.details.cause);
if (error.details.remoteDoc) {
console.log('Remote doc info:', error.details.remoteDoc);
}
}
}
// Custom document loader error handling
jsonld.documentLoader = async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new JsonLdError(
`HTTP ${response.status}: ${response.statusText}`,
'jsonld.LoadDocumentError',
{
code: 'loading document failed',
url: url,
status: response.status
}
);
}
return {
contextUrl: null,
document: await response.json(),
documentUrl: response.url
};
} catch (fetchError) {
throw new JsonLdError(
'Network error loading document',
'jsonld.LoadDocumentError',
{
code: 'loading document failed',
url: url,
cause: fetchError
}
);
}
};Errors related to invalid JSON-LD syntax or structure.
Error Names:
jsonld.SyntaxError: Invalid JSON-LD syntaxjsonld.InvalidTypeValue: Invalid @type value formatCommon Scenarios:
try {
// Invalid @type value (must be string or array of strings)
const doc = {
"@type": {invalid: "object"}
};
await jsonld.expand(doc);
} catch (error) {
if (error.name === 'jsonld.SyntaxError') {
console.log('Syntax error:', error.message);
console.log('Invalid value:', error.details.value);
console.log('Error code:', error.details.code); // 'invalid type value'
}
}Errors that occur during RDF operations.
Error Names:
jsonld.CanonizeError: Canonicalization/normalization errorsjsonld.UnknownFormat: Unknown input/output formatjsonld.UnknownDocumentLoader: Unknown document loader typeCommon Scenarios:
try {
// Unknown input format
await jsonld.canonize(input, {inputFormat: 'application/turtle'});
} catch (error) {
if (error.name === 'jsonld.CanonizeError') {
console.log('Canonicalization failed:', error.message);
}
}
try {
// Unknown output format
await jsonld.toRDF(doc, {format: 'application/turtle'});
} catch (error) {
if (error.name === 'jsonld.UnknownFormat') {
console.log('Unknown format:', error.details.format);
}
}Errors during context processing and resolution.
Error Names:
jsonld.InvalidLocalContext: Invalid local context structurejsonld.InvalidRemoteContext: Invalid remote contextjsonld.RecursiveContextInclusion: Circular context referencesCommon Scenarios:
try {
await jsonld.processContext({}, circularContext);
} catch (error) {
if (error.name === 'jsonld.RecursiveContextInclusion') {
console.log('Circular context reference detected');
console.log('Context chain:', error.details.contextChain);
}
}const handleJsonLdError = async (operation) => {
try {
return await operation();
} catch (error) {
if (error instanceof JsonLdError) {
console.error(`JSON-LD Error [${error.name}]:`, error.message);
if (error.details) {
console.error('Details:', error.details);
}
} else {
console.error('Unexpected error:', error);
}
throw error;
}
};
// Usage
const result = await handleJsonLdError(() =>
jsonld.compact(doc, context)
);const compactWithFallback = async (doc, context, fallbackContext) => {
try {
return await jsonld.compact(doc, context);
} catch (error) {
if (error.name === 'jsonld.LoadDocumentError') {
console.warn('Primary context failed, trying fallback:', error.message);
return await jsonld.compact(doc, fallbackContext);
}
throw error;
}
};const validateAndExpand = async (doc) => {
// Pre-validate document structure
if (!doc || typeof doc !== 'object') {
throw new JsonLdError(
'Document must be a non-null object',
'jsonld.InvalidInput',
{document: doc}
);
}
try {
return await jsonld.expand(doc, {safe: true});
} catch (error) {
if (error.name === 'jsonld.SyntaxError') {
// Handle syntax errors specifically
console.error('Document has invalid JSON-LD syntax');
console.error('Problem with:', error.details.value);
return null; // or return a default/cleaned version
}
throw error;
}
};const safeJsonLdOperation = async (operation, ...args) => {
try {
// Always use safe mode for operations
const options = args[args.length - 1] || {};
args[args.length - 1] = {...options, safe: true};
return await operation(...args);
} catch (error) {
if (error.name?.startsWith('jsonld.')) {
// Log JSON-LD specific errors but don't crash
console.warn('JSON-LD operation failed safely:', error.message);
return null;
}
throw error; // Re-throw non-JSON-LD errors
}
};
// Usage
const compacted = await safeJsonLdOperation(jsonld.compact, doc, context);
if (compacted === null) {
// Handle the failure case
console.log('Compaction failed, using original document');
}const loadDocumentWithRetry = async (url, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await jsonld.get(url);
} catch (error) {
if (error.name === 'jsonld.LoadDocumentError' && attempt < maxRetries) {
console.warn(`Load attempt ${attempt} failed, retrying...`);
// Wait before retry (exponential backoff)
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
continue;
}
throw error;
}
}
};const processContextWithFallbacks = async (activeCtx, contexts) => {
for (const context of contexts) {
try {
return await jsonld.processContext(activeCtx, context);
} catch (error) {
console.warn(`Context failed: ${context}`, error.message);
continue; // Try next context
}
}
throw new JsonLdError(
'All context options failed',
'jsonld.ContextProcessingError',
{contexts, lastError: error}
);
};/**
* JSON-LD error details structure
*/
interface JsonLdErrorDetails {
/**
* Error code identifier
*/
code?: string;
/**
* URL that caused the error (for loading errors)
*/
url?: string;
/**
* HTTP status code (for HTTP errors)
*/
status?: number;
/**
* The value that caused the error
*/
value?: any;
/**
* Context information
*/
context?: any;
/**
* Remote document information
*/
remoteDoc?: RemoteDocument;
/**
* Underlying cause of the error
*/
cause?: Error;
/**
* Additional context-specific details
*/
[key: string]: any;
}
/**
* Common JSON-LD error names
*/
type JsonLdErrorName =
| 'jsonld.CompactError'
| 'jsonld.LoadDocumentError'
| 'jsonld.NullRemoteDocument'
| 'jsonld.InvalidUrl'
| 'jsonld.SyntaxError'
| 'jsonld.InvalidTypeValue'
| 'jsonld.CanonizeError'
| 'jsonld.UnknownFormat'
| 'jsonld.UnknownDocumentLoader'
| 'jsonld.InvalidLocalContext'
| 'jsonld.InvalidRemoteContext'
| 'jsonld.RecursiveContextInclusion'
| 'jsonld.OptionsError';
/**
* Error handler function type
*/
type ErrorHandler = (error: JsonLdError) => void | Promise<void>;