Skip to content

fix(msteams): add fetch timeout to Microsoft Graph API calls#47860

Closed
hclsys wants to merge 1 commit intoopenclaw:mainfrom
hclsys:fix/msteams-graph-fetch-timeout
Closed

fix(msteams): add fetch timeout to Microsoft Graph API calls#47860
hclsys wants to merge 1 commit intoopenclaw:mainfrom
hclsys:fix/msteams-graph-fetch-timeout

Conversation

@hclsys
Copy link
Copy Markdown
Contributor

@hclsys hclsys commented Mar 16, 2026

lobster-biscuit

Problem

fetchGraphJson() in the MS Teams extension calls the Microsoft Graph API without any timeout. If the Graph endpoint hangs or is slow to respond, the entire extension stalls indefinitely.

Solution

Add a 30-second AbortSignal.timeout to the central fetchGraphJson() wrapper. This single change protects every Graph API call in the MS Teams extension (list teams, list channels, etc.).

The fetch is wrapped in a try/catch that preserves the cause chain via { cause: err }. The existing !res.ok error path already uses .catch(() => "") on the body read, so no change needed there.

Changes

  • extensions/msteams/src/graph.ts — add AbortSignal.timeout(30_000) to fetch + try/catch wrapper

Test plan

  • TypeScript compiles
  • oxlint passes
  • Existing MS Teams tests pass (no test file for graph.ts)

🤖 Generated with Claude Code

fetchGraphJson() had no timeout, so a hanging Microsoft Graph
endpoint would stall the entire MS Teams extension indefinitely.

Add a 30-second AbortSignal.timeout and wrap the fetch in a
try/catch that preserves the cause chain.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: HCL <[email protected]>
@openclaw-barnacle openclaw-barnacle bot added channel: msteams Channel integration: msteams size: XS labels Mar 16, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 16, 2026

Greptile Summary

This PR adds a 30-second AbortSignal.timeout to the central fetchGraphJson() wrapper in the MS Teams extension, preventing indefinite hangs when the Microsoft Graph API is slow or unresponsive. The change is small, well-scoped, and correctly applies to all callers (listTeamsByName, listChannelsForTeam, etc.) through the single wrapper.

Key observations:

  • The fetch call is now wrapped in a try/catch that re-throws with a consistent "Graph … request failed" message and preserves the original error via { cause: err } — a good pattern.
  • The AbortSignal.timeout() static method is available in Node.js ≥ 17.3 / modern browsers; since TypeScript compilation reportedly succeeds, the project's runtime targets are assumed to support it.
  • Minor inconsistency: the res.json() call on the happy path (line 58) sits outside the try/catch, so a body-parse failure will bubble up as a raw SyntaxError rather than the wrapped format used for network errors — worth aligning for consistency.

Confidence Score: 4/5

  • This PR is safe to merge — it adds a defensive timeout with no functional regression risk.
  • The change is minimal (one file, ~10 lines added) and solves a real problem (indefinite hang on slow Graph API calls). The only minor gap is that the res.json() body read on the success path is outside the new try/catch, leaving a slightly inconsistent error format for parse failures. This does not affect correctness or stability.
  • No files require special attention beyond the minor res.json() error-wrapping inconsistency noted in extensions/msteams/src/graph.ts.

Comments Outside Diff (1)

  1. extensions/msteams/src/graph.ts, line 58 (link)

    res.json() not covered by try/catch

    The res.json() call on the success path sits outside the new try/catch block. If the response body is malformed or the stream is interrupted, the resulting SyntaxError (or other rejection) will bubble up un-wrapped, bypassing the consistent "Graph … request failed" error format that was just introduced for network-level failures.

    Consider wrapping the body read as well for consistent error handling:

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/msteams/src/graph.ts
Line: 58

Comment:
**`res.json()` not covered by try/catch**

The `res.json()` call on the success path sits outside the new try/catch block. If the response body is malformed or the stream is interrupted, the resulting `SyntaxError` (or other rejection) will bubble up un-wrapped, bypassing the consistent `"Graph … request failed"` error format that was just introduced for network-level failures.

Consider wrapping the body read as well for consistent error handling:

```suggestion
  return (await res.json().catch((err: unknown) => {
    throw new Error(
      `Graph ${params.path} response parse failed: ${err instanceof Error ? err.message : String(err)}`,
      { cause: err },
    );
  })) as T;
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 51409b8

@hclsys hclsys closed this Mar 17, 2026
BradGroux added a commit to BradGroux/openclaw that referenced this pull request Mar 19, 2026
Resolved:
- openclaw#25790 (Teams issue, CLOSED)
- openclaw#47860 (Teams PR, CLOSED)
- openclaw#48116 (Azure issue, CLOSED)
- openclaw#48899 (Azure issue, CLOSED)
- openclaw#47898 (Azure PR, MERGED)
- openclaw#17970 (Azure PR, CLOSED)
- openclaw#21678 (Windows issue, CLOSED)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: msteams Channel integration: msteams size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant