Configuration - Node.js

3 min read Updated: 11.09.2026

Options worth knowing

OptionDefaultMeaning
token, privateKey-project credentials; both required to send anything
urlhttps://dockray.ioaddress of the DockRay instance
environmentNODE_ENV or productionenvironment column in the panel
release-version of the deployed application
sampleRate1share of error events sent
tracesSampleRate0share of transactions sent; 0 disables tracing
sendDefaultPiifalsekeeps the IP address and user agent on events
appRootprocess.cwd()frames below this path are marked as application code
contextLines3source lines kept around each application frame
timeout5000send timeout, in milliseconds
beforeSend-receives the event, returns it, a changed copy, or null to drop it

Environments

Every environment should report under an unambiguous name - production, staging, preview. The name is a column in the panel and a filter on the error list, so without it a production outage looks exactly like an error someone triggered in a test. Leave your local environment without credentials: with no token and no key the integration loads and stays silent, so you do not need a separate switch to turn it off.

When events are sent

A visitor never waits on the monitoring service. report() queues a send without awaiting it, keeping a reference to the promise so the process cannot exit mid-flight:

js
ray.report(ray.captureException(error));

The framework adapters call this on an event that only fires after the response has been sent. The queue holds at most 50 concurrent reports for the whole process; anything beyond that is dropped silently, with no log entry. sampleRate and tracesSampleRate decide what fraction of events even reaches it: 1 always sends, 0 never does, anything in between is rolled independently per call. By default errors go out in full and transactions do not go out at all.

The Express and Fastify adapters

Both adapters name transactions after the route pattern rather than the concrete address - GET /orders/:id, not GET /orders/8123 - so one route stays one row in the panel no matter how many identifiers passed through it. By default they skip /health and /metrics (ignorePaths), report only 5xx responses (shouldReport), and strip Authorization, Cookie and X-Api-Key from the reported headers. The visitor's IP address is read from X-Forwarded-For or X-Real-IP before falling back to the socket address.

js
import express from 'express';
import { rayRequestHandler, rayErrorHandler } from '@dockcodes/dock-ray/express';

const app = express();

app.use(rayRequestHandler(ray));      // before the routes
// ... routes ...
app.use(rayErrorHandler(ray));        // after the routes

rayRequestHandler opens a transaction and reports it on the response's finish event. rayErrorHandler reports the error and passes it on - it never swallows one, so your own error page still renders.

js
import { rayPlugin } from '@dockcodes/dock-ray/fastify';

await fastify.register(rayPlugin, { client: ray });

The Fastify equivalent of finish is the onResponse hook - transactions are reported from there, and errors from onError.

Browser errors

A browser cannot authenticate with DockRay directly - the private key has to stay on the server. A report that reached one of your routes is relayed like this:

js
app.post('/api/ray/browser', async (req, res) => {
    ray.report(ray.captureBrowserReport(req.body, {
        pageUrl: req.headers.referer,
        userAgent: req.headers['user-agent'],
    }));

    res.status(202).json({ success: true });
});

The payload is untrusted: unrecognised fields are dropped, every string is capped at 1 KB, the stack at 50 frames, and anything that cannot become an event returns false. The envelope - id, timestamp, environment, release - is filled in here, on the server, so a browser never chooses which environment its errors land in. The page-side collector is a separate entry point, @dockcodes/dock-ray/browser; you write the endpoint's guards yourself, as the shipped CMS integrations do.

Protecting the private key

The private key is a project secret, not an identifier. Keep it in environment variables, in a secrets manager or in the server configuration - never in the repository, in logs, in a screenshot or in code sent to the browser. One project can hold many keys, so production and staging should each get their own: either can be revoked on its own without interrupting the others. A suspicion that a key leaked is reason enough to revoke it and generate a new one.

Next Verification and common problems - Node.js
Chat with us The chat is closed right now Available: Mo–Fr 08:00–18:00