technical-debt-radar 1.6.1 → 1.6.3

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.
Files changed (2) hide show
  1. package/dist/index.js +43 -27
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16219,7 +16219,23 @@ var require_reliability_detector = __commonJS({
16219
16219
  detectUnboundedParallelCalls(sourceFile, file.path, fns, policy, violations);
16220
16220
  project.removeSourceFile(sourceFile);
16221
16221
  }
16222
- return applyExceptions(violations, policy);
16222
+ return applyExceptions(deduplicateOverlapping(violations), policy);
16223
+ }
16224
+ function deduplicateOverlapping(violations) {
16225
+ const hasMissingTryCatch = /* @__PURE__ */ new Set();
16226
+ for (const v of violations) {
16227
+ if (v.ruleId === shared_1.RELIABILITY_RULES.MISSING_TRY_CATCH) {
16228
+ hasMissingTryCatch.add(`${v.file}:${v.function ?? ""}`);
16229
+ }
16230
+ }
16231
+ return violations.filter((v) => {
16232
+ if (v.ruleId === shared_1.RELIABILITY_RULES.UNHANDLED_PROMISE_REJECTION) {
16233
+ const key = `${v.file}:${v.function ?? ""}`;
16234
+ if (hasMissingTryCatch.has(key))
16235
+ return false;
16236
+ }
16237
+ return true;
16238
+ });
16223
16239
  }
16224
16240
  function collectFunctions(sourceFile, filePath) {
16225
16241
  const scopes = [];
@@ -16597,39 +16613,39 @@ var require_reliability_detector = __commonJS({
16597
16613
  continue;
16598
16614
  if (isNestJSControllerMethod(fn.node, _sourceFile))
16599
16615
  continue;
16600
- let hasAwait = false;
16601
- fn.node.forEachDescendant((child) => {
16602
- if (ts_morph_1.Node.isAwaitExpression(child))
16603
- hasAwait = true;
16604
- });
16605
- if (!hasAwait)
16606
- continue;
16607
16616
  const body = fn.node.getBody();
16608
16617
  if (!body || !ts_morph_1.Node.isBlock(body))
16609
16618
  continue;
16610
- const hasTryAtTop = body.getStatements().some((s) => ts_morph_1.Node.isTryStatement(s));
16611
- if (hasTryAtTop)
16612
- continue;
16613
- let hasTryNested = false;
16614
- body.forEachDescendant((child) => {
16615
- if (hasTryNested)
16616
- return;
16619
+ let unhandledAwaitCount = 0;
16620
+ let totalAwaitCount = 0;
16621
+ fn.node.forEachDescendant((child) => {
16617
16622
  if (child !== fn.node && (ts_morph_1.Node.isFunctionDeclaration(child) || ts_morph_1.Node.isMethodDeclaration(child) || ts_morph_1.Node.isArrowFunction(child) || ts_morph_1.Node.isFunctionExpression(child)))
16618
16623
  return;
16619
- if (ts_morph_1.Node.isTryStatement(child))
16620
- hasTryNested = true;
16621
- });
16622
- if (hasTryNested)
16623
- continue;
16624
- let awaitCount = 0;
16625
- fn.node.forEachDescendant((child) => {
16626
- if (ts_morph_1.Node.isFunctionDeclaration(child) || ts_morph_1.Node.isMethodDeclaration(child) || ts_morph_1.Node.isArrowFunction(child) || ts_morph_1.Node.isFunctionExpression(child)) {
16627
- if (child !== fn.node)
16628
- return;
16624
+ if (!ts_morph_1.Node.isAwaitExpression(child))
16625
+ return;
16626
+ totalAwaitCount++;
16627
+ let current = child.getParent();
16628
+ let isHandled = false;
16629
+ while (current && current !== fn.node) {
16630
+ if (ts_morph_1.Node.isTryStatement(current)) {
16631
+ const tryBlock = current.getTryBlock();
16632
+ if (tryBlock && child.getPos() >= tryBlock.getPos() && child.getEnd() <= tryBlock.getEnd()) {
16633
+ isHandled = true;
16634
+ }
16635
+ break;
16636
+ }
16637
+ if (ts_morph_1.Node.isFunctionDeclaration(current) || ts_morph_1.Node.isMethodDeclaration(current) || ts_morph_1.Node.isArrowFunction(current) || ts_morph_1.Node.isFunctionExpression(current))
16638
+ break;
16639
+ current = current.getParent();
16629
16640
  }
16630
- if (ts_morph_1.Node.isAwaitExpression(child))
16631
- awaitCount++;
16641
+ if (!isHandled)
16642
+ unhandledAwaitCount++;
16632
16643
  });
16644
+ if (totalAwaitCount === 0)
16645
+ continue;
16646
+ if (unhandledAwaitCount === 0)
16647
+ continue;
16648
+ const awaitCount = unhandledAwaitCount;
16633
16649
  if (awaitCount < 2)
16634
16650
  continue;
16635
16651
  violations.push(makeViolation(shared_1.RELIABILITY_RULES.MISSING_TRY_CATCH, filePath, fn.node.getStartLineNumber(), `Async function '${fn.name}' has multiple awaits but no try/catch`, policy, fn.name, "Add try/catch around the async operations or use an error-handling wrapper"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "Stop Node.js production crashes before merge. 47 detection patterns across 5 categories.",
5
5
  "bin": {
6
6
  "radar": "dist/index.js",