> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/operations/debugging.md).

# Debugging

Techniques and tools for diagnosing DNotifier SDK issues during development and staging. Use this guide before escalating to [Troubleshooting](/product-docs/operations/troubleshooting.md) for production incidents.

***

## Enable verbose logging in your app

The SDK does not ship a global debug flag. Wrap SDK callbacks with your own logging:

```js
const notifier = new DNotifier({
  // ...
  onConnected: () => {
    console.log("[DNotifier] connected", {
      isConnected: notifier.isConnected,
      aiEnabled: notifier.aiEnabled,
      messageSizeLimit: notifier.messageSizeLimit,
      limits: notifier.getPlanLimits(),
    });
  },
  onMessage: (msg) => {
    console.log("[DNotifier] message", {
      sender: msg.metadata.sender,
      type: msg.metadata.type,
      id: msg.metadata.id,
      payload: msg.payload.toJSON(),
    });
  },
  onDisconnected: () => {
    console.log("[DNotifier] disconnected");
  },
});
```

```dart
onConnected: () {
  debugPrint('Connected: ${notifier.isConnected}');
  debugPrint('Limits: ${notifier.getPlanLimits()}');
},
onMessage: (msg) {
  debugPrint('From ${msg.metadata.sender}: ${msg.payload.toJSON()}');
},
```

{% hint style="info" %}
Redact secrets and PII from logs before sharing them with support.
{% endhint %}

***

## Verify authentication first

Most issues trace to auth or transport misconfiguration. Run this minimal check:

### JavaScript (Node.js)

```js
import WebSocket from "ws";
import { DNotifier } from "@dnotifier-realtime/dnotifier";

const notifier = new DNotifier({
  appId: process.env.DNOTIFIER_APP_ID,
  secret: process.env.DNOTIFIER_SECRET,
  transport: "ws",
  userId: "debug-user",
  WebSocketImpl: WebSocket,
  onConnected: () => console.log("OK"),
  onMessage: () => {},
  onDisconnected: () => {},
});

try {
  await notifier.connect();
  console.log("authToken present:", Boolean(notifier.authToken));
  console.log("limits:", notifier.getPlanLimits());
} catch (e) {
  console.error("FAIL:", e.message);
}
```

### Dart

```dart
final notifier = DNotifier(
  appId: 'your-app-id',
  secret: 'your-app-secret',
  transport: 'ws',
  userId: 'debug-user',
  onConnected: () => print('OK'),
);
await notifier.connect();
print('authToken: ${notifier.authToken}');
print('limits: ${notifier.getPlanLimits()}');
```

***

## Inspect connection lifecycle

Expected WebSocket sequence:

1. Authenticate over HTTPS
2. Receive auth token and plan limits
3. Open WebSocket (WSS) to the production host
4. Handshake with token
5. `onConnected` fires

→ [Connection lifecycle](/product-docs/realtime-communication/connection-lifecycle.md) · [Endpoints & custom URL](/product-docs/reference/endpoints.md)

Use browser DevTools **Network → WS** to inspect frames in web clients.

***

## Transport-specific debugging

| Transport      | Check                                                            |
| -------------- | ---------------------------------------------------------------- |
| `ws` (Node)    | `WebSocketImpl` passed? `ws` package installed?                  |
| `ws` (browser) | No `WebSocketImpl` needed; check CSP `connect-src`               |
| `http`         | `connect()` completes but no socket — normal; test `sendAI` next |
| Dart / Flutter | Same endpoints; no `WebSocketImpl` required                      |

→ [Choose your transport](/product-docs/getting-started/choose-transport.md)

***

## Message flow debugging

### Outbound

Log every `send()` with `senderId`, `receiverId`, and payload type:

```js
console.log("send →", { receiverId, type: data.type });
await notifier.send({ senderId, receiverId, data });
```

### Inbound

Confirm `onMessage` is registered **before** `connect()`. Messages arriving during connect are rare but callbacks must exist.

### Chunked messages

If large payloads never appear complete:

* Confirm `messageSizeLimit` on both sender and receiver plans
* Wait for full reassembly — only complete messages invoke `onMessage`
* Browser clients: the SDK configures the socket for binary payloads automatically

→ [Large messages & chunking](/product-docs/realtime-communication/chunking.md)

***

## AI and workflow debugging

| Feature         | Debug approach                                             |
| --------------- | ---------------------------------------------------------- |
| `sendAI`        | Log full response object; check `aiEnabled`                |
| `search`        | Log `hits` length and similarity scores                    |
| Workflows       | Set `observability: true`; find `executionId` in dashboard |
| Session logging | Set `logs: true`; verify sessions in AI logs dashboard     |

```js
const run = await notifier.runWorkflow({ workflow, input: "test" });
console.log({ executionId: run.executionId, result: run.result, state: run.state });
```

Catch `WorkflowError` for validation failures:

```js
try {
  await notifier.runWorkflow({ workflow, input });
} catch (err) {
  if (err.name === "WorkflowError") {
    console.error("Workflow failed:", err.message);
  }
  throw err;
}
```

→ [Workflow observability](/product-docs/workflows-and-agents/observability.md)

***

## Dashboard tools

| Dashboard area                                 | Use for                      |
| ---------------------------------------------- | ---------------------------- |
| [app.dnotifier.com](https://app.dnotifier.com) | App credentials, plan, usage |
| AI session logs                                | When `logs: true`            |
| Workflow executions                            | When `observability: true`   |

***

## Custom WebSocket URL

Override the WebSocket URL only when DNotifier has provided a dedicated host:

```js
const notifier = new DNotifier({
  // ...
  url: "wss://YOUR_HOST",
  WebSocketImpl: WebSocket,
});
```

→ [Endpoints & custom URL](/product-docs/reference/endpoints.md)

***

## Common mistakes checklist

| Mistake                           | Symptom                                            |
| --------------------------------- | -------------------------------------------------- |
| `send()` before `await connect()` | `WebSocket not connected` / `StateError`           |
| Wrong `userId` as `receiverId`    | Message "sent" but peer never receives             |
| HTTP transport for chat           | No realtime `onMessage` delivery                   |
| Secret in browser bundle          | Auth works in dev, security incident in prod       |
| Duplicate `userId` on two tabs    | Both receive messages for that ID — often intended |

***

## Next steps

* [Troubleshooting](/product-docs/operations/troubleshooting.md) — production issue playbooks
* [FAQ](/product-docs/operations/faq.md)
* [Support & links](/product-docs/appendix/support.md)
