Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Make sure StorybookError message shows up in browser console and interactions panel #28464

Merged
merged 13 commits into from
Jul 7, 2024
Prev Previous commit
Next Next commit
fix eslint issues and migrate detection to the new error format
  • Loading branch information
yannbf committed Jul 5, 2024
commit 4e4e6c0466b62f4c3629c8bda133c65d296b35df
2 changes: 1 addition & 1 deletion code/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ module.exports = {
},
},
{
files: ['**/core-events/src/**/*'],
files: ['./core/src/preview-errors.ts'],
excludedFiles: ['**/*.test.*'],
rules: {
'local-rules/no-duplicated-error-codes': 'error',
Expand Down
71 changes: 49 additions & 22 deletions scripts/eslint-plugin-local-rules/no-duplicated-error-codes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,62 @@ module.exports = {
create(context) {
const errorClasses = {};

// both code and category are passed as arguments to the StorybookError constructor's super call
function findSuperArguments(node) {
let superArguments = [];

node.body.body.forEach((method) => {
if (method.type === 'MethodDefinition' && method.kind === 'constructor') {
method.value.body.body.forEach((expression) => {
if (
expression.type === 'ExpressionStatement' &&
expression.expression.type === 'CallExpression' &&
expression.expression.callee.type === 'Super'
) {
superArguments = expression.expression.arguments;
}
});
}
});

return superArguments;
}

return {
ClassDeclaration(node) {
if (node.superClass.name === 'StorybookError') {
const categoryProperty = node.body.body.find((prop) => {
return prop.type === 'PropertyDefinition' && prop.key.name === 'category';
});
if (node.superClass && node.superClass.name === 'StorybookError') {
const superArguments = findSuperArguments(node);
const properties = {
category: null,
code: null,
};

const codeProperty = node.body.body.find((prop) => {
return prop.type === 'PropertyDefinition' && prop.key.name === 'code';
// Process the arguments to extract category and code
superArguments.forEach((arg) => {
if (arg.type === 'ObjectExpression') {
arg.properties.forEach((property) => {
if (Object.keys(properties).includes(property.key.name)) {
properties[property.key.name] = property;
}
});
}
});

if (categoryProperty && categoryProperty.value.type === 'MemberExpression') {
const categoryName = categoryProperty.value.property.name;
const categoryValue = properties.category.value.property.name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧠 logic: Potential issue if properties.category or properties.code is null. Consider adding a null check.

const codeValue = properties.code.value.value;

if (codeProperty && codeProperty.value.type === 'Literal') {
const errorCode = codeProperty.value.value;

if (!errorClasses[categoryName]) {
errorClasses[categoryName] = new Set();
}
if (categoryValue && codeValue) {
if (!errorClasses[categoryValue]) {
errorClasses[categoryValue] = new Set();
}

if (errorClasses[categoryName].has(errorCode)) {
context.report({
node: codeProperty,
message: `Duplicate error code '${errorCode}' in category '${categoryName}'.`,
});
} else {
errorClasses[categoryName].add(errorCode);
}
if (errorClasses[categoryValue].has(codeValue)) {
context.report({
node: properties.code.key,
message: `Duplicate error code '${codeValue}' in category '${categoryValue}'.`,
});
} else {
errorClasses[categoryValue].add(codeValue);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
description: 'Disallow usage of the Error JavaScript class.',
category: 'Best Practices',
recommended: true,
url: 'https://github.com/storybookjs/storybook/blob/next/code/lib/core-events/src/errors/README.md',
url: 'https://github.com/storybookjs/storybook/blob/next/code/core/src/ERRORS.md',
},
},
create(context) {
Expand Down
Loading