123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 'use strict';
- const {getStaticValue} = require('@eslint-community/eslint-utils');
- const isShadowed = require('./utils/is-shadowed.js');
- const {callOrNewExpressionSelector} = require('./selectors/index.js');
- const MESSAGE_ID_MISSING_MESSAGE = 'missing-message';
- const MESSAGE_ID_EMPTY_MESSAGE = 'message-is-empty-string';
- const MESSAGE_ID_NOT_STRING = 'message-is-not-a-string';
- const messages = {
- [MESSAGE_ID_MISSING_MESSAGE]: 'Pass a message to the `{{constructorName}}` constructor.',
- [MESSAGE_ID_EMPTY_MESSAGE]: 'Error message should not be an empty string.',
- [MESSAGE_ID_NOT_STRING]: 'Error message should be a string.',
- };
- const selector = callOrNewExpressionSelector([
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
- 'Error',
- 'EvalError',
- 'RangeError',
- 'ReferenceError',
- 'SyntaxError',
- 'TypeError',
- 'URIError',
- 'InternalError',
- 'AggregateError',
- ]);
- /** @param {import('eslint').Rule.RuleContext} context */
- const create = context => ({
- [selector](expression) {
- if (isShadowed(context.getScope(), expression.callee)) {
- return;
- }
- const constructorName = expression.callee.name;
- const messageArgumentIndex = constructorName === 'AggregateError' ? 1 : 0;
- const callArguments = expression.arguments;
- // If message is `SpreadElement` or there is `SpreadElement` before message
- if (callArguments.some((node, index) => index <= messageArgumentIndex && node.type === 'SpreadElement')) {
- return;
- }
- const node = callArguments[messageArgumentIndex];
- if (!node) {
- return {
- node: expression,
- messageId: MESSAGE_ID_MISSING_MESSAGE,
- data: {constructorName},
- };
- }
- // These types can't be string, and `getStaticValue` may don't know the value
- // Add more types, if issue reported
- if (node.type === 'ArrayExpression' || node.type === 'ObjectExpression') {
- return {
- node,
- messageId: MESSAGE_ID_NOT_STRING,
- };
- }
- const staticResult = getStaticValue(node, context.getScope());
- // We don't know the value of `message`
- if (!staticResult) {
- return;
- }
- const {value} = staticResult;
- if (typeof value !== 'string') {
- return {
- node,
- messageId: MESSAGE_ID_NOT_STRING,
- };
- }
- if (value === '') {
- return {
- node,
- messageId: MESSAGE_ID_EMPTY_MESSAGE,
- };
- }
- },
- });
- /** @type {import('eslint').Rule.RuleModule} */
- module.exports = {
- create,
- meta: {
- type: 'problem',
- docs: {
- description: 'Enforce passing a `message` value when creating a built-in error.',
- },
- messages,
- },
- };
|