Skip to content
Permalink
Browse files

fix(eslint-plugin): [no-throw-literal] false positive with logical ex…

…pressions (#2645)
  • Loading branch information
jsone-studios committed Oct 11, 2020
1 parent 8e44c78 commit 57aa6c7642320074ed2b6a15e7f38e66a2fb13d1
@@ -61,40 +61,6 @@ export default util.createRule({
return false;
}

function tryGetThrowArgumentType(node: TSESTree.Node): ts.Type | null {
switch (node.type) {
case AST_NODE_TYPES.Identifier:
case AST_NODE_TYPES.CallExpression:
case AST_NODE_TYPES.NewExpression:
case AST_NODE_TYPES.MemberExpression:
case AST_NODE_TYPES.TSAsExpression: {
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
return checker.getTypeAtLocation(tsNode);
}

case AST_NODE_TYPES.AssignmentExpression:
return tryGetThrowArgumentType(node.right);

case AST_NODE_TYPES.SequenceExpression:
return tryGetThrowArgumentType(
node.expressions[node.expressions.length - 1],
);

case AST_NODE_TYPES.LogicalExpression: {
const left = tryGetThrowArgumentType(node.left);
return left ?? tryGetThrowArgumentType(node.right);
}

case AST_NODE_TYPES.ConditionalExpression: {
const consequent = tryGetThrowArgumentType(node.consequent);
return consequent ?? tryGetThrowArgumentType(node.alternate);
}

default:
return null;
}
}

function checkThrowArgument(node: TSESTree.Node): void {
if (
node.type === AST_NODE_TYPES.AwaitExpression ||
@@ -103,20 +69,20 @@ export default util.createRule({
return;
}

const type = tryGetThrowArgumentType(node);
if (type) {
if (type.flags & ts.TypeFlags.Undefined) {
context.report({ node, messageId: 'undef' });
return;
}
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
const type = checker.getTypeAtLocation(tsNode);

if (
util.isTypeAnyType(type) ||
util.isTypeUnknownType(type) ||
isErrorLike(type)
) {
return;
}
if (type.flags & ts.TypeFlags.Undefined) {
context.report({ node, messageId: 'undef' });
return;
}

if (
util.isTypeAnyType(type) ||
util.isTypeUnknownType(type) ||
isErrorLike(type)
) {
return;
}

context.report({ node, messageId: 'object' });
@@ -61,14 +61,13 @@ throw new CustomError();
`
class CustomError1 extends Error {}
class CustomError2 extends CustomError1 {}
throw new CustomError();
throw new CustomError2();
`,
'throw (foo = new Error());',
'throw (1, 2, new Error());',
"throw 'literal' && new Error();",
"throw new Error() || 'literal';",
"throw foo ? new Error() : 'literal';",
"throw foo ? 'literal' : new Error();",
'throw foo ? new Error() : new Error();',
`
function* foo() {
let index = 0;
@@ -112,6 +111,18 @@ declare const foo: Error | string;
throw foo as Error;
`,
'throw new Error() as Error;',
`
declare const nullishError: Error | undefined;
throw nullishError ?? new Error();
`,
`
declare const nullishError: Error | undefined;
throw nullishError || new Error();
`,
`
declare const nullishError: Error | undefined;
throw nullishError ? nullishError : new Error();
`,
],
invalid: [
{
@@ -207,19 +218,31 @@ throw a + 'b';
},
{
code: "throw 'literal' && 'not an Error';",
errors: [
{
messageId: 'object',
},
],
errors: [{ messageId: 'object' }],
},
{
code: "throw 'literal' || new Error();",
errors: [{ messageId: 'object' }],
},
{
code: "throw new Error() && 'literal';",
errors: [{ messageId: 'object' }],
},
{
code: "throw 'literal' ?? new Error();",
errors: [{ messageId: 'object' }],
},
{
code: "throw foo ? 'not an Error' : 'literal';",
errors: [
{
messageId: 'object',
},
],
errors: [{ messageId: 'object' }],
},
{
code: "throw foo ? new Error() : 'literal';",
errors: [{ messageId: 'object' }],
},
{
code: "throw foo ? 'literal' : new Error();",
errors: [{ messageId: 'object' }],
},
{
code: 'throw `${err}`;',

0 comments on commit 57aa6c7

Please sign in to comment.
You can’t perform that action at this time.