Fetch


⚙️ _fetch (fetchWithLogging) — Internal Fetch Wrapper

Overview

_fetch is a globally available, logging-enhanced wrapper around the native fetch API.
It provides automatic timeout handling, structured logging, redaction of sensitive data, and configurable request inspection — all without changing the core fetch syntax.

Use _fetch for all HTTP requests inside helper functions or services that require observability and safe logging.


✳️ Usage Example

const res = await _fetch("https://api.example.com/v1/data", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({ name: "Alice", password: "secret" }),
  options: {
    timeoutMs: 5000,
    logBody: true,
    logHeaders: true,
    logQueryValues: true,
    excludePatterns: [/password/i],
    excludeMode: "redact",
  },
});

const data = await res.json();

🧩 Key Features

FeatureDescription
Timeout controlAutomatically cancels requests after timeoutMs milliseconds using AbortController.
Structured loggingEmits a logger.log("http_response", {...}) event with request, response, and timing details.
Header/body scrubbingAutomatically removes or redacts sensitive fields using regular expressions.
Signal combinationCombines user-provided and internal signals so either can abort the request.
Query/response captureLogs both request and response URLs (with final redirects, if applicable).
Drop-in compatibleFully compatible with native fetch — same syntax, same return type.
Injects identifying headersAdds headers to each request identifying point, organization, and user making the request.

🧱 Function Signature

await _fetch(input, init);
ParameterTypeDescription
input`stringRequest`The URL or a pre-built Request object.
initobjectStandard fetch init options (method, headers, body, signal, etc.).
init.optionsobjectExtended logging and behavior controls (see below).

⚙️ Extended Options (init.options)

OptionTypeDefaultDescription
timeoutMsnumberundefinedAborts the request if it exceeds this duration (in ms).
logBodybooleanfalseInclude request body in logs (with sensitive fields removed/redacted).
logHeadersbooleanfalseInclude request headers in logs.
logQueryValuesbooleantrueInclude query string values in logs (non-sensitive values only).
captureResponseUrlbooleantrueLog the final response URL (useful for redirects).
excludePatternsRegExp[][]List of key patterns to omit or redact from logs.
excludeMode`"omit""redact"`"omit"How to handle excluded keys (omit deletes them; redact replaces with [EXCLUDED]).
metadataobject{}Custom metadata to include in the log output (merged with system metadata).

🧰 Logging Behavior

Every _fetch call automatically produces a structured log record with the tag http_response.
This object includes both request and response metadata.

Example log object

{
  "point_name": "arc_engine_api",
  "method": "POST",
  "url": "https://api.example.com/v1/data",
  "domain": "api.example.com",
  "path": "/v1/data",
  "query": { "page": "1" },
  "body": { "name": "Alice", "password": "[EXCLUDED]" },
  "requestHeaders": { "content-type": "application/json", "authorization": "[REDACTED]" },
  "status": 200,
  "ok": true,
  "duration": 312,
  "final_url": "https://api.example.com/v1/data",
  "response_content_type": "application/json"
}

🔐 Redaction and Exclusion Rules

_fetch automatically prevents sensitive data from being logged.

Built-in protections:

  • Header keys like authorization, cookie, or x-api-key are redacted automatically.
  • Query parameters containing token, secret, pass, key, session, or signature are replaced with [REDACTED].
  • Body fields are sanitized using excludePatterns.

Custom redaction examples:

options: {
  excludePatterns: [/password/i, /^x-private-/i],
  excludeMode: "omit",
}

This will remove all matching keys entirely from logs.


⏱️ Timeout and Abort Logic

  • If timeoutMs is set, _fetch creates an internal AbortController to cancel the request after that duration.
  • If the user also provides a signal, both signals are combined — either one can abort the request.
  • When a timeout occurs, _fetch throws:
    Error("Request timed out after <timeoutMs>ms").

🧾 Returned Value

_fetch returns the same object as native fetch — a standard Response instance.
All of the following methods work the same way:

const res = await _fetch(url);
const text = await res.text();
const json = await res.json();
const ok = res.ok;
const status = res.status;

If a network error occurs, _fetch throws an Error (never returns an incomplete Response).


📦 Integration Example (inside a helper)

async function createUser({ payload, timeoutMs = 10000 }) {
  const res = await _fetch(`${api_host}/v1/users`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(payload),
    options: {
      timeoutMs,
      logBody: true,
      logHeaders: true,
      excludePatterns: [/password/i],
      excludeMode: "redact",
    },
  });

  if (!res.ok) throw new Error(`Failed to create user: ${res.status}`);
  return await res.json();
}

📋 Best Practices

Always use _fetch instead of fetch to ensure consistent logging.
✅ Use excludePatterns aggressively to avoid logging secrets.
✅ Prefer redact over omit to maintain visibility into removed keys.
✅ Set timeoutMs for all network calls — unbounded requests can hang indefinitely.
✅ Avoid logging large binary bodies; _fetch already truncates long bodies with an ellipsis ().
✅ Don’t catch and suppress _fetch errors silently — propagate them with context.


🧩 Advanced: Injected Headers

_fetch automatically injects context headers for observability:

HeaderDescription
x-options-point-nameName of the current point (if available).
x-options-point-organization-idOrganization ID in context.
x-options-point-userCurrent user (if defined globally).

These are added transparently to every request unless overridden.


🧠 Summary

_fetch is a global, enhanced replacement for the native fetch function — it behaves the same but adds structured logging, timeouts, and automatic redaction of sensitive data. Use it for all HTTP requests inside helpers or services to ensure secure and consistent observability.

const res = await _fetch("https://api.example.com/v1/data", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ name: "Alice", password: "secret" }),
  options: {
    timeoutMs: 5000,
    logBody: true,
    logHeaders: true,
    excludePatterns: [/password/i],
    excludeMode: "redact",
  },
});
const data = await res.json();

You can use all standard fetch methods (res.json(), res.text(), etc.), but _fetch will automatically log request and response details, redact sensitive fields, and enforce timeouts — no extra setup required.


Maintained by: Platform Engineering
Function: _fetch (alias: fetchWithLogging)
Version: 1.0
Scope: Global — available to all helper modules