Skip to content

Commit

Permalink
Merge pull request #13 from mattolson/error-handling
Browse files Browse the repository at this point in the history
v2.0.0: Update error handling
  • Loading branch information
mattolson authored Jan 24, 2018
2 parents b3a13db + 6d2e45d commit e49a7f7
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 230 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@

## 1.0.0
- Initial extraction from stencil-paper

## 2.0.0
- Change error handling to throw custom errors instead of swallowing the error
and logging. This gives the caller the opportunity to take action based on
the error condition.
- Remove logging interface since we don't use it anymore.
97 changes: 52 additions & 45 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
'use strict';

const _ = require('lodash');
const Logger = require('./lib/logger');
const HandlebarsV3 = require('handlebars');
const HandlebarsV4 = require('@bigcommerce/handlebars-v4');
const helpers = require('./helpers');

const AppError = require('./lib/appError');
class CompileError extends AppError {}; // Error compiling template
class FormatError extends AppError {}; // Error restoring precompiled template
class RenderError extends AppError {}; // Error rendering template
class DecoratorError extends AppError {}; // Error applying decorator
class TemplateNotFoundError extends AppError {}; // Template not registered

const handlebarsOptions = {
preventIndent: true
};

// HandlebarsRenderer implements the interface Paper requires for its
// rendering needs, and does so with Handlebars.
class HandlebarsRenderer {
// Add static accessor to reference custom errors
static get errors() {
return {
CompileError,
FormatError,
RenderError,
DecoratorError,
TemplateNotFoundError,
};
}

/**
* Constructor
*
Expand All @@ -35,7 +52,6 @@ class HandlebarsRenderer {
this._translator = null;
this._decorators = [];
this._contentRegions = {};
this._logger = new Logger();

// Build global context for helpers
this.helperContext = {
Expand All @@ -53,24 +69,6 @@ class HandlebarsRenderer {
});
}

/**
* Set the logger for us to use.
*
* @param {Object} An object that responds to `info`, `warn`, and `error`.
*/
setLogger(logger) {
this._logger = logger;
};

/**
* Get logger
*
* @return {Object} Logger
*/
logger() {
return this._logger;
};

/**
* Set the paper.Translator instance used to translate strings in helpers.
*
Expand Down Expand Up @@ -102,15 +100,13 @@ class HandlebarsRenderer {

// Check if it is a precompiled template
try {
// If precompiled, restore function
template = this._tryRestoringPrecompiled(template);

// Register it with handlebars
this.handlebars.registerPartial(path, template);
} catch(e) {
// Swallow the error, but log it
this.logger().error(e);
throw new FormatError(e.message);
}

// Register it with handlebars
this.handlebars.registerPartial(path, template);
});
};

Expand Down Expand Up @@ -156,8 +152,7 @@ class HandlebarsRenderer {
try {
processed[path] = this.handlebars.precompile(template, handlebarsOptions);
} catch(e) {
// Swallow the error, but log it
this.logger().error(e);
throw new CompileError(e.message, { path });
}
});
return processed;
Expand Down Expand Up @@ -197,39 +192,41 @@ class HandlebarsRenderer {
* @param {String} path
* @param {Object} context
* @return {String}
* @throws [TemplateNotFoundError|RenderError|DecoratorError]
*/
render(path, context) {
context = context || {};
context.template = path;

// Add some data to the context
context.template = path;
if (this._translator) {
context.locale_name = this._translator.getLocale();
}

// Look up the template
const template = this.handlebars.partials[path];
if (typeof template === 'undefined') {
// Swallow the error, but log it
this.logger().error(`template not found: ${path}`);
return '';
throw new TemplateNotFoundError(`template not found: ${path}`);
}

let output;
// Render the template
let result;
try {
// Render the template
output = template(context);
result = template(context);
} catch(e) {
throw new RenderError(e.message);
}

// Apply decorators
// Apply decorators
try {
_.each(this._decorators, fn => {
output = fn(output);
result = fn(result);
});
} catch(e) {
// Swallow the error, but log it
this.logger().error(e);
output = '';
throw new DecoratorError(e.message);
}

return output;
return result;
};

/**
Expand All @@ -238,17 +235,27 @@ class HandlebarsRenderer {
* @param {String} template
* @param {Object} context
* @return {String}
* @throws [CompileError|RenderError]
*/
renderString(template, context) {
context = context || {};

// Compile the template
try {
template = this.handlebars.compile(template);
} catch(e) {
throw new CompileError(e.message);
}

// Render the result
let result;
try {
return this.handlebars.compile(template)(context);
result = template(context);
} catch(e) {
// Swallow the error, but log it
this.logger().error(e);
return '';
throw new RenderError(e.message);
}

return result;
}
}

Expand Down
19 changes: 19 additions & 0 deletions lib/appError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

class AppError extends Error {
constructor(message, details) {
// Calling parent constructor of base Error class.
super(message);

// Saving class name in the property of our custom error as a shortcut.
this.name = this.constructor.name;

// Capturing stack trace, excluding constructor call from it.
Error.captureStackTrace(this, this.constructor);

// Store extra details for caller to diagnose error
this.details = details || {};
}
};

module.exports = AppError;
39 changes: 0 additions & 39 deletions lib/logger.js

This file was deleted.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bigcommerce/stencil-paper-handlebars",
"version": "1.0.0",
"version": "2.0.0",
"description": "A paper plugin to render pages using Handlebars.js",
"main": "index.js",
"author": "Bigcommerce",
Expand Down Expand Up @@ -33,7 +33,6 @@
"devDependencies": {
"code": "~4.0.0",
"eslint": "~4.10.0",
"intercept-stdout": "^0.1.2",
"lab": "~13.0.4",
"sinon": "~2.1.0"
}
Expand Down
Loading

0 comments on commit e49a7f7

Please sign in to comment.