# Deep Promise Chain
# Detects promise chains 4+ levels deep
id: deep-promise-chain
name: Deep Promise Chain (4+ levels)
severity: warning
category: complexity
defect_class: async-misuse
inline_tier: warning
language: typescript

message: "Promise chain {{M1}} → {{M2}} → {{M3}} → {{M4}} — consider async/await"

description: |
  Deep promise chains (4+ levels) are hard to read and debug.
  Async/await provides clearer control flow.
  
  ✅ FIX: Convert to async/await

query: |
  (call_expression
    function: (member_expression
      object: (call_expression
        function: (member_expression
          object: (call_expression
            function: (member_expression
              object: (call_expression
                function: (member_expression
                  property: (property_identifier) @M1)
                arguments: (arguments))
              property: (property_identifier) @M2)
            arguments: (arguments))
          property: (property_identifier) @M3)
        arguments: (arguments))
      property: (property_identifier) @M4)
    arguments: (arguments)
    (#match? @M1 "^(then|catch|finally)$")
    (#match? @M2 "^(then|catch|finally)$")
    (#match? @M3 "^(then|catch|finally)$")
    (#match? @M4 "^(then|catch|finally)$"))

metavars:
  - M1
  - M2
  - M3
  - M4

tags:
  - complexity
  - async
  - readability

examples:
  bad: |
    fetch('/api')
      .then(r => r.json())
      .catch(e => console.log(e))
      .then(data => data.items)
      .then(items => items[0])
      .then(first => process(first));
  
  good: |
    async function fetchFirstItem() {
      try {
        const response = await fetch('/api');
        const data = await response.json();
        const items = data.items;
        const first = items[0];
        return process(first);
      } catch (e) {
        console.log(e);
      }
    }

has_fix: true
fix_action: convert_to_async_await
