Skip to content

Commit

Permalink
Refactoring of custom errors, drop SyntaxError from export
Browse files Browse the repository at this point in the history
  • Loading branch information
lahmatiy committed Jan 22, 2020
1 parent 3355b15 commit ab09af1
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 71 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- Removed `element()` specific parsing rules
- Changed `String` node type to store decoded string value (and auto encode a value on serialize)
- Changed `Url` node type to store decoded url value (and auto encode a value on serialize)
- Removed `SyntaxError` (custom parse error class) from public API
- Removed `parseError` field in parse `SyntaxError`

## 1.0.0-alpha.39 (December 5, 2019)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ module.exports = function createCustomError(name, message) {
const error = Object.create(SyntaxError.prototype);
const errorStack = new Error();

error.name = name;
error.message = message;

Object.defineProperty(error, 'stack', {
get: function() {
return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
return Object.assign(error, {
name,
message,
get stack() {
return (errorStack.stack || '').replace(/^(.+\n){1,3}/, `${name}: ${message}\n`);
}
});

return error;
};
20 changes: 9 additions & 11 deletions lib/definition-syntax/SyntaxError.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
const createCustomError = require('../utils/create-custom-error');
const createCustomError = require('../common/create-custom-error');

module.exports = function SyntaxError(message, input, offset) {
const error = createCustomError('SyntaxError', message);

error.input = input;
error.offset = offset;
error.rawMessage = message;
error.message = error.rawMessage + '\n' +
' ' + error.input + '\n' +
'--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';

return error;
return Object.assign(createCustomError('SyntaxError', message), {
input,
offset,
rawMessage: message,
message: message + '\n' +
' ' + input + '\n' +
'--' + new Array((offset || input.length) + 1).join('-') + '^'
});
};
45 changes: 22 additions & 23 deletions lib/lexer/error.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
const createCustomError = require('../utils/create-custom-error');
const createCustomError = require('../common/create-custom-error');
const generate = require('../definition-syntax/generate');

function fromMatchResult(matchResult) {
const tokens = matchResult.tokens;
const longestMatch = matchResult.longestMatch;
const { tokens, longestMatch } = matchResult;
const node = longestMatch < tokens.length ? tokens[longestMatch].node : null;
let mismatchOffset = -1;
let entries = 0;
Expand Down Expand Up @@ -58,33 +57,33 @@ const SyntaxReferenceError = function(type, referenceName) {
return error;
};

const MatchError = function(message, syntax, node, matchResult) {
const error = createCustomError('SyntaxMatchError', message);
const MatchError = function(message, syntaxAst, node, matchResult) {
const details = fromMatchResult(matchResult);
const mismatchOffset = details.mismatchOffset || 0;
const badNode = details.node || node;
const end = getLocation(badNode, 'end');
const start = details.last ? end : getLocation(badNode, 'start');
const css = details.css;
const syntax = syntaxAst ? generate(syntaxAst) : '<generic>';

error.rawMessage = message;
error.syntax = syntax ? generate(syntax) : '<generic>';
error.css = css;
error.mismatchOffset = mismatchOffset;
error.loc = {
source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
start,
end
};
error.line = start ? start.line : undefined;
error.column = start ? start.column : undefined;
error.offset = start ? start.offset : undefined;
error.message = message + '\n' +
' syntax: ' + error.syntax + '\n' +
' value: ' + (error.css || '<empty string>') + '\n' +
' --------' + '-'.repeat(error.mismatchOffset) + '^';

return error;
return Object.assign(createCustomError('SyntaxMatchError', message), {
rawMessage: message,
syntax,
css,
mismatchOffset,
loc: {
source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
start,
end
},
line: start ? start.line : undefined,
column: start ? start.column : undefined,
offset: start ? start.offset : undefined,
message: message + '\n' +
' syntax: ' + syntax + '\n' +
' value: ' + (css || '<empty string>') + '\n' +
' --------' + '-'.repeat(mismatchOffset) + '^'
});
};

module.exports = {
Expand Down
38 changes: 14 additions & 24 deletions lib/common/SyntaxError.js → lib/parser/SyntaxError.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const createCustomError = require('../utils/create-custom-error');
const createCustomError = require('../common/create-custom-error');
const MAX_LINE_LENGTH = 100;
const OFFSET_CORRECTION = 60;
const TAB_REPLACEMENT = ' ';

function sourceFragment(error, extraLines) {
function sourceFragment({ source, line, column }, extraLines) {
function processLines(start, end) {
return lines
.slice(start, end)
Expand All @@ -12,12 +12,10 @@ function sourceFragment(error, extraLines) {
).join('\n');
}

const lines = error.source.split(/\r\n?|\n|\f/);
const line = error.line;
const lines = source.split(/\r\n?|\n|\f/);
const startLine = Math.max(1, line - extraLines) - 1;
const endLine = Math.min(line + extraLines, lines.length + 1);
const maxNumLength = Math.max(4, String(endLine).length) + 1;
let column = error.column;
let cutLeft = 0;

// column correction according to replaced tab before column
Expand Down Expand Up @@ -46,29 +44,21 @@ function sourceFragment(error, extraLines) {
}

module.exports = function SyntaxError(message, source, offset, line, column) {
const error = createCustomError('SyntaxError', message);

error.source = source;
error.offset = offset;
error.line = line;
error.column = column;

error.sourceFragment = extraLines => sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
Object.defineProperty(error, 'formattedMessage', {
get() {
const error = Object.assign(createCustomError('SyntaxError', message), {
source,
offset,
line,
column,
sourceFragment(extraLines) {
return sourceFragment({ source, line, column }, isNaN(extraLines) ? 0 : extraLines);
},
get formattedMessage() {
return (
'Parse error: ' + error.message + '\n' +
sourceFragment(error, 2)
`Parse error: ${message}\n` +
sourceFragment({ source, line, column }, 2)
);
}
});

// for backward capability
error.parseError = {
offset,
line,
column
};

return error;
};
3 changes: 2 additions & 1 deletion lib/parser/create.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const OffsetToLocation = require('../common/OffsetToLocation');
const SyntaxError = require('../common/SyntaxError');
const TokenStream = require('../common/TokenStream');
const List = require('../common/List');
const SyntaxError = require('./SyntaxError');
const tokenize = require('../tokenizer');
const { findWhiteSpaceStart, cmpChar, cmpStr } = require('../tokenizer/utils');
const NAME = require('../tokenizer/names');
Expand Down Expand Up @@ -306,6 +306,7 @@ module.exports = function createParser(config) {
};

return Object.assign(parse, {
SyntaxError,
config: parser.config
});
};
2 changes: 0 additions & 2 deletions lib/syntax/create.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const List = require('../common/List');
const SyntaxError = require('../common/SyntaxError');
const TokenStream = require('../common/TokenStream');
const Lexer = require('../lexer/Lexer');
const definitionSyntax = require('../definition-syntax');
Expand All @@ -23,7 +22,6 @@ function createSyntax(config) {

const syntax = {
List,
SyntaxError,
TokenStream,
Lexer,

Expand Down
8 changes: 6 additions & 2 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ function createParseErrorTest(name, test, options) {
() => parse(test.source, options),
(e) => {
error = e;
if (e.parseError) {
if (e instanceof parse.SyntaxError === false) {
return true;
}
},
'Should be a CSS parse error'
);

assert.equal(error.message, test.error);
assert.deepEqual(error.parseError, test.position);
assert.deepEqual({
offset: error.offset,
line: error.line,
column: error.column
}, test.position);
});
}

Expand Down

0 comments on commit ab09af1

Please sign in to comment.