Skip to main content
Version: 1.1.0

Client Error Reporting Endpoint

Version: 1.1.0 Date: 2026-07-15

Goal: Allow front-end applications (IP Magic Box, Tower, etc.) to report client-side errors to the backend for centralized monitoring, support triage, and error-catalog matching.

Solution: New client-errors domain with a throttled POST endpoint for error creation and a GET endpoint (admin-only) for querying errors with filters and pagination.

API contract

POST /api/v2/client-errors

Auth: Bearer API token (same as other neo routes).

Headers:

HeaderRequiredDescription
AuthorizationYesBearer <api-token>
Bcyip-AgentNoSource identifier (e.g. ipmagicbox, iptower). Defaults to unknown if omitted.
Content-TypeYesapplication/json

Rate limit: 60 requests/minute per IP (ThrottlerGuard).

Request body (CreateClientErrorDto):

{
"appVersion": "4.37.0",
"taskType": "Upload",
"error": [
{
"name": "FileUploadError",
"message": "Could not upload file to Sharepoint",
"stack": "FileUploadError: ...",
"code": "optional-string"
}
],
"context": {
"os": "darwin",
"arch": "arm64",
"fileName": "contract.pdf",
"fileSize": 1048576
}
}
FieldTypeRequiredNotes
appVersionstringYesClient semver (IP Magic Box package.json version)
taskTypestringNoPipeline stage when error occurred (e.g. Upload, Anchor)
errorarrayYesMin 1 item. Serialized error chain — see IP Magic Box IPBError.serialize()
contextobjectNoFree-form diagnostic context (OS, file metadata, hash, etc.)

Each error[] item (IP Magic Box convention):

FieldTypeRequired
namestringYes
messagestringYes
stackstringYes
codestringNo

Nested causes are additional array elements (outer error first, cause chain flattened).

Response: 201 — MongoDB insertedId (ObjectId string).

Stored document (server-enriched):

{
"appVersion": "4.37.0",
"taskType": "Upload",
"error": [ "..." ],
"context": { "..." },
"userId": "<ObjectId>",
"jobId": "<ObjectId>",
"companyRef": "<ObjectId>",
"source": "ipmagicbox",
"createdAt": "2026-07-15T12:00:00.000Z"
}

GET /api/v2/client-errors (admin only)

Auth: Bearer token with Role.Admin.

Query params (QueryClientErrorDto):

ParamTypeDefaultDescription
companyRefObjectId stringFilter by company
userIdObjectId stringFilter by user
sourcestringFilter by Bcyip-Agent value
taskTypestringFilter by task stage
dateFromISO date stringcreatedAt >=
dateToISO date stringcreatedAt <=
pagenumber1Page index
limitnumber50Page size

Response: { items: ClientError[], total: number, page, limit }

Implementation Details

  • Collection: clientErrors
  • TTL index on createdAt — auto-delete after 90 days (expireAfterSeconds: 7776000)
  • Compound indexes: { companyRef, createdAt }, { source, createdAt }, { userId, createdAt }
  • IP Magic Box: fire-and-forget reportClientError() with per-task deduplication (reportedErrorTaskIds)

Files Modified:

  • src/domains/client-error/client-error.module.ts
  • src/domains/client-error/client-error.controller.ts
  • src/domains/client-error/client-error.service.ts
  • src/domains/client-error/dto/create-client-error.dto.ts
  • src/domains/client-error/dto/query-client-error.dto.ts
  • src/domains/client-error/client-error.service.spec.ts
  • src/domains/client-error/client-error.controller.spec.ts

Release fragment: feat-client-error-endpoint