@croct/cache
Version:
An abstraction layer for caching.
80 lines (79 loc) • 2.59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorResilientCache = void 0;
const logging_1 = require("@croct/logging");
/**
* A wrapper that indicates the wrapped error originated on the fresh data loader.
*
* This allows the error handling logic to differentiate an error that originated on the
* wrapped cache provider from an error that originated from the caller-provider data loader.
*/
class LoaderError extends Error {
constructor(internal) {
super('Loader error.');
this.internal = internal;
}
}
/**
* A cache wrapper that prevents any error from the wrapped cache from propagating to the caller.
*
* Errors retrieving values from the cache behave as a cache miss.
* Errors retrieving a fresh value from the loader are propagated unchanged.
*/
class ErrorResilientCache {
constructor(cache, logger) {
this.cache = cache;
this.logger = logger;
this.logProviderError = this.logProviderError.bind(this);
}
get(key, loader) {
return this.cache
.get(key, async (loaderKey) => {
try {
return await loader(loaderKey);
}
catch (error) {
throw new LoaderError(error);
}
})
.catch(error => {
if (error instanceof LoaderError) {
this.logLoaderError(error.internal);
throw error.internal;
}
this.logProviderError(error);
return loader(key);
});
}
set(key, value) {
return this.cache
.set(key, value)
.catch(this.logProviderError);
}
delete(key) {
return this.cache
.delete(key)
.catch(this.logProviderError);
}
logLoaderError(error) {
this.logger.log({
level: logging_1.LogLevel.ERROR,
message: 'Error detected on cache loader.',
details: {
errorMessage: (0, logging_1.extractErrorMessage)(error),
errorStack: error instanceof Error ? error.stack : undefined,
},
});
}
logProviderError(error) {
this.logger.log({
level: logging_1.LogLevel.ERROR,
message: 'Suppressed error on cache operation',
details: {
errorMessage: (0, logging_1.extractErrorMessage)(error),
errorStack: error instanceof Error ? error.stack : undefined,
},
});
}
}
exports.ErrorResilientCache = ErrorResilientCache;