@fjall/eslint-plugin 2.23.1 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
* - `<expr>.error.reason` / `<expr>.error?.reason`
|
|
10
10
|
* - `<bareErrorBinding>.message` / `.reason` where the binding name is
|
|
11
11
|
* `err`, `error`, `cause`, or `rejection` (common error-handler param)
|
|
12
|
+
* - `<anyBinding>.message` inside a ConditionalExpression branch whose test
|
|
13
|
+
* proves error-ness name-independently: the consequent of
|
|
14
|
+
* `X instanceof Error ? X.message : …` (RHS: any Identifier matching
|
|
15
|
+
* /Error$/ — `Error` itself or a custom ctor), or
|
|
16
|
+
* the alternate of `!(X instanceof Error) ? … : X.message`. The
|
|
17
|
+
* same-identifier requirement between test and leaf is strict, and the
|
|
18
|
+
* check is AST-local (no interprocedural inference).
|
|
12
19
|
* - `<expr>.reason` (Promise rejection / settled-result shape)
|
|
13
20
|
* - `<expr>.error` / `<expr>.errorMessage` — server-error envelope reads.
|
|
14
21
|
* The webapp's JSON failure shape is `{ error: string }` or
|
|
@@ -325,6 +332,14 @@ function classifyErrorLeaf(node, context) {
|
|
|
325
332
|
return { label: `${object.name}.${propName}`, shape: "strict" };
|
|
326
333
|
}
|
|
327
334
|
|
|
335
|
+
if (
|
|
336
|
+
propName === "message" &&
|
|
337
|
+
object.type === "Identifier" &&
|
|
338
|
+
isInInstanceofProvenErrorBranch(node, object.name)
|
|
339
|
+
) {
|
|
340
|
+
return { label: `${object.name}.message`, shape: "strict" };
|
|
341
|
+
}
|
|
342
|
+
|
|
328
343
|
if (propName === "reason" && object.type === "Identifier") {
|
|
329
344
|
return { label: `${object.name}.reason`, shape: "strict" };
|
|
330
345
|
}
|
|
@@ -386,6 +401,62 @@ function classifyErrorLeaf(node, context) {
|
|
|
386
401
|
return null;
|
|
387
402
|
}
|
|
388
403
|
|
|
404
|
+
/**
|
|
405
|
+
* True when `node` (an `X.message` MemberExpression, `X` an Identifier named
|
|
406
|
+
* `bindingName`) sits in a ConditionalExpression branch whose test proves
|
|
407
|
+
* `X instanceof Error`: the consequent of `X instanceof Error ? … : …`, or
|
|
408
|
+
* the alternate of `!(X instanceof Error) ? … : …`. The instanceof test
|
|
409
|
+
* proves error-ness name-independently, so bindings outside
|
|
410
|
+
* ERROR_BINDING_NAMES qualify. The identifier match between test and leaf is
|
|
411
|
+
* strict; the walk is AST-local and stops at function boundaries. A leaf in
|
|
412
|
+
* a ternary TEST position never qualifies (boolean check, not value flow).
|
|
413
|
+
*/
|
|
414
|
+
function isInInstanceofProvenErrorBranch(node, bindingName) {
|
|
415
|
+
let child = node;
|
|
416
|
+
let parent = node.parent;
|
|
417
|
+
while (parent) {
|
|
418
|
+
if (
|
|
419
|
+
parent.type === "FunctionDeclaration" ||
|
|
420
|
+
parent.type === "FunctionExpression" ||
|
|
421
|
+
parent.type === "ArrowFunctionExpression" ||
|
|
422
|
+
parent.type === "Program"
|
|
423
|
+
) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
if (parent.type === "ConditionalExpression") {
|
|
427
|
+
if (parent.test === child) return false;
|
|
428
|
+
if (
|
|
429
|
+
parent.consequent === child &&
|
|
430
|
+
isInstanceofErrorTest(parent.test, bindingName)
|
|
431
|
+
) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
if (
|
|
435
|
+
parent.alternate === child &&
|
|
436
|
+
parent.test.type === "UnaryExpression" &&
|
|
437
|
+
parent.test.operator === "!" &&
|
|
438
|
+
isInstanceofErrorTest(parent.test.argument, bindingName)
|
|
439
|
+
) {
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
child = parent;
|
|
444
|
+
parent = parent.parent;
|
|
445
|
+
}
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function isInstanceofErrorTest(test, bindingName) {
|
|
450
|
+
return (
|
|
451
|
+
test.type === "BinaryExpression" &&
|
|
452
|
+
test.operator === "instanceof" &&
|
|
453
|
+
test.left.type === "Identifier" &&
|
|
454
|
+
test.left.name === bindingName &&
|
|
455
|
+
test.right.type === "Identifier" &&
|
|
456
|
+
CUSTOM_ERROR_CTOR_RE.test(test.right.name)
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
|
|
389
460
|
/**
|
|
390
461
|
* Returns true when `objectNode` is an Identifier bound from a
|
|
391
462
|
* `<schema>.safeParse(...)` call. `parsed.error` in that shape is a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/eslint-plugin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.0",
|
|
4
4
|
"description": "ESLint plugin with Fjall-specific coding standard rules",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"vitest": "^4.1.5"
|
|
33
33
|
},
|
|
34
34
|
"license": "SEE LICENSE IN LICENSE",
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "7c1a329184064aefa557c2c09de0965c4f8cd4fb"
|
|
36
36
|
}
|