@botonic/plugin-contentful
Version:
Botonic Plugin Contentful is one of the **[available](https://github.com/hubtype/botonic/tree/master/packages)** plugins for Botonic. **[Contentful](http://www.contentful.com)** is a CMS (Content Management System) which manages contents of a great variet
194 lines • 7.59 kB
JavaScript
import { __awaiter } from "tslib";
/* eslint-disable @typescript-eslint/unbound-method */
import { MultiError } from 'async-parallel';
import { Measure } from '../util';
import { reduceMultiError } from '../util/async';
import { AssetId, ContentId } from './callback';
import { ContentType, CustomContentType, DEFAULT_REFERENCES_TO_INCLUDE, } from './cms';
import { DEFAULT_CONTEXT } from './context';
import { CmsException } from './exceptions';
/**
* It validates the individually delivered contents, but not those fetched
* through contents/topContents
*/
export class ErrorReportingCMS {
constructor(cms, logger) {
this.cms = cms;
this.logger = logger;
this.exceptionWrapper = new ContentfulExceptionWrapper('CMS', logger);
}
validate(content, context) {
const validation = content.validate();
if (validation) {
const locale = (context === null || context === void 0 ? void 0 : context.locale) ? ` on locale '${context.locale}'` : '';
const msg = `${content.contentType} ${content.toString()}${locale}: ${validation}`;
if (this.logger)
this.logger(msg);
else
console.error(msg);
}
return content;
}
catchAndValidate(id, context, contentType, promise) {
return __awaiter(this, void 0, void 0, function* () {
const m = new Measure('cms.' + contentType);
try {
const c = yield promise;
m.end();
this.validate(c, context);
return c;
}
catch (e) {
this.handleContentError(contentType, id, context)(e);
throw new Error('should not reach here');
}
});
}
carousel(id, context) {
return this.catchAndValidate(id, context, ContentType.CAROUSEL, this.cms.carousel(id, context));
}
document(id, context) {
return this.catchAndValidate(id, context, ContentType.DOCUMENT, this.cms.document(id, context));
}
handoff(id, context) {
return this.catchAndValidate(id, context, ContentType.HANDOFF, this.cms.handoff(id, context));
}
input(id, context) {
return this.catchAndValidate(id, context, ContentType.INPUT, this.cms.input(id, context));
}
custom(id, context) {
return this.catchAndValidate(id, context, CustomContentType.CUSTOM, this.cms.custom(id, context));
}
text(id, context) {
return this.catchAndValidate(id, context, ContentType.TEXT, this.cms.text(id, context));
}
chitchat(id, context) {
return this.catchAndValidate(id, context, ContentType.CHITCHAT, this.cms.chitchat(id, context));
}
startUp(id, context) {
return this.catchAndValidate(id, context, ContentType.STARTUP, this.cms.startUp(id, context));
}
url(id, context) {
return this.catchAndValidate(id, context, ContentType.URL, this.cms.url(id, context));
}
payload(id, context) {
return this.catchAndValidate(id, context, ContentType.PAYLOAD, this.cms.payload(id, context));
}
image(id, context) {
return this.catchAndValidate(id, context, ContentType.IMAGE, this.cms.image(id, context));
}
video(id, context) {
return this.catchAndValidate(id, context, ContentType.VIDEO, this.cms.video(id, context));
}
queue(id, context) {
return this.catchAndValidate(id, context, ContentType.QUEUE, this.cms.queue(id, context));
}
button(id, context) {
return this.catchAndValidate(id, context, ContentType.BUTTON, this.cms.button(id, context));
}
element(id, context) {
return this.catchAndValidate(id, context, ContentType.ELEMENT, this.cms.element(id, context));
}
contentsWithKeywords(context, paging) {
return this.cms
.contentsWithKeywords(context, paging)
.catch(this.handleError('contentsWithKeywords', {}, context));
}
topContents(model, context, filter, paging) {
return __awaiter(this, void 0, void 0, function* () {
const m = new Measure('topContents.' + model);
const contents = yield this.cms
.topContents(model, context, filter, paging)
.catch(this.handleError('topContents', { model }, context));
m.end();
return contents;
});
}
content(id, context = DEFAULT_CONTEXT, referencesToInclude = DEFAULT_REFERENCES_TO_INCLUDE) {
return this.cms
.content(id, context, referencesToInclude)
.catch(this.handleContentError('content', id, context));
}
contents(model, context, paging) {
return this.cms
.contents(model, context, paging)
.catch(this.handleError('contents', { model }, context));
}
assets(context) {
return this.cms
.assets(context)
.catch(this.handleError('assets', {}, context));
}
schedule(id, context) {
return this.cms
.schedule(id, context)
.catch(this.handleContentError(ContentType.SCHEDULE, id, context));
}
dateRange(id, context) {
return this.cms
.dateRange(id, context)
.catch(this.handleContentError(ContentType.DATE_RANGE, id, context));
}
asset(id, context) {
return this.cms
.asset(id, context)
.catch(this.handleResourceError(new AssetId(id, undefined), context));
}
handleContentError(contentType, id, context) {
return this.handleResourceError(ContentId.create(contentType, id), context);
}
handleResourceError(resourceId, context) {
return (reason) => {
throw this.exceptionWrapper.wrap(reason, resourceId.resourceType, resourceId, {}, context);
};
}
handleError(method, args, context) {
return (reason) => {
throw this.exceptionWrapper.wrap(reason, method, undefined, args, context);
};
}
}
export class ContentfulExceptionWrapper {
constructor(wrappee, logger = (msg) => {
console.error(msg);
}) {
this.wrappee = wrappee;
this.logger = logger;
// TODO add logStack in plugin config
this.logStack = true;
}
wrap(contentfulError, method, resourceId, args, context) {
let content = '';
if (context === null || context === void 0 ? void 0 : context.locale) {
content += ` with locale '${context.locale}'`;
}
if (resourceId) {
content += ` on ${resourceId.toString()}`;
}
if (Object.keys(args).length) {
content += ` with args '${JSON.stringify(args)}'`;
}
const msg = `Error calling ${this.wrappee}.${method}${content}`;
const exception = new CmsException(msg, contentfulError, resourceId);
const err = this.processError(contentfulError);
this.logger(`${msg} Due to ${err}`);
throw exception;
}
processError(contentfulError) {
let err = '';
if (contentfulError instanceof MultiError) {
err += ' Due to:';
for (const e of reduceMultiError(contentfulError)) {
err += this.processError(e);
}
}
else if (this.logStack && contentfulError.stack) {
err += contentfulError.stack.split('\n').slice(0, 5).join('\n');
}
else {
err += `Due to '${contentfulError.message}'`;
}
return err;
}
}
//# sourceMappingURL=cms-error.js.map