Add a structured `problem+json` error response format alongside the current shape
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- nodejs, typescript
Research direction
Start with the GlobalExceptionFilter registered in src/app.module.ts (around lines 302-305), then read the validation pipe's error construction in src/common/pipes/validation.pipe.ts (lines 55-64) and the string-typed throw in src/blockchain/oracle/services/submitter.service.ts (line 229). The issue leaves the backward-compatibility approach open, so confirm that choice with maintainers before editing. Done means every error response has a string message, the existing errors[] shape is preserved, and the affected specs and docs/openapi.json are updated.
Written by the indexing model from the issue text.
Description
Problem
Error responses are shaped ad hoc. There is a GlobalExceptionFilter registered at src/app.module.ts:302-305, and the validation pipe produces a specific shape (src/common/pipes/validation.pipe.ts:55-64):
return new BadRequestException({
statusCode: 400,
error: "Bad Request",
message: allMessages.length > 0 ? allMessages : "Validation failed",
errors: formattedErrors,
});
Meanwhile message is sometimes a string and sometimes an array — here it is an array, but a plain throw new BadRequestException("Payload has expired") (src/blockchain/oracle/services/submitter.service.ts:229) produces a string. Controllers return ad-hoc envelopes too, for example { success: true, file: {...} } in file-upload.controller.ts:92-105. Success and error envelopes are therefore not uniform, and message is inconsistently typed.
Why it matters
A polymorphic message field is a persistent SDK-generation problem: the generated TypeScript client has to type it as string | string[], so every consumer writes defensive code. It also means clients cannot reliably distinguish a field-level validation failure from an arbitrary thrown string. RFC 9457 (application/problem+json) is the standardised answer, is widely understood, and generators increasingly support it.
The README's "Developer friendly — typed APIs, clear contracts" principle (line 30) is not met by a message field that is sometimes a string and sometimes an array.
Suggested Direction
- Adopt RFC 9457 as the error format:
type,title,status,detail,instance, plus extension members for field errors. - Implement it in the existing
GlobalExceptionFilter, so every thrown exception is normalised in one place. That is the highest-leverage single change available. - Make
messagea string always, moving field-level detail into a structurederrorsarray that preserves the current shape fromformatValidationErrors()({ field, constraints, messages, children }) — clients already depend on that shape. - Decide on backward compatibility. Changing the error envelope breaks clients. Options: add
problem+jsonas a negotiated format viaAccept, or add the problem fields alongside the existing ones for a deprecation period. Recommend the latter for a v0.1.0 project — announce, add fields, remove later. - Standardise success envelopes too, or make them consistently bare payloads. The current mix of bare returns and
{ success: true, ... }wrappers means clients check per endpoint.
Constraints
src/common/pipes/validation.pipe.tshas tests and clients depend on theerrors[].field/constraints/childrenstructure — preserve it.- Some existing specs assert on error bodies; they will need updating, which is expected but should be called out.
- Any breaking change regenerates
docs/openapi.jsonand both SDKs. - Do not leak stack traces or internal error messages in the
detailfield — the filter should sanitiseInternalServerError.
Acceptance Criteria
- All thrown exceptions produce a consistent, documented error shape via
GlobalExceptionFilter. -
messageis a string on every error response. - Field-level validation errors retain the existing
errors[]structure. - Internal errors do not expose stack traces or internal messages.
- Success and error envelope conventions are documented in
docs/. -
docs/openapi.jsonand the SDKs are regenerated and the diff reviewed.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 55
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SourceXXL/alian_structure-api
-
good first issue help wanted security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#266 ·
-
Parallelize the cache-warming loop in `cache-warming.service.ts` — warmers run strictly sequentiallyPossibly taken @syntaxsuuvam-spec claimed this 4 days ago. Opengood first issue performance
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#240 ·
-
documentation help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
SourceXXL/alian_structure-api#215 ·
-
good first issue refactor tooling
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
SourceXXL/alian_structure-api#199 ·
-
help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
SourceXXL/alian_structure-api#196 ·
All issues in SourceXXL/alian_structure-api
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
wormhole-foundation/wormhole#5062 ·
Maintainers usually reply within 1 day
-
internal os specific
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
frostney/GocciaScript#1688 ·
Maintainers usually reply within 1 day
-
integration:hermes
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
vectorize-io/hindsight#5592 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
vercel/streamdown#673 · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
apache/rocketmq-dashboard#6712 ·
Maintainers usually reply within 3 days