Skip to content

fix: Unable to parse response body the throw the HTTP error #1509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
TokugawaTakeshi opened this issue May 2, 2025 · 7 comments
Open

fix: Unable to parse response body the throw the HTTP error #1509

TokugawaTakeshi opened this issue May 2, 2025 · 7 comments
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.

Comments

@TokugawaTakeshi
Copy link

TokugawaTakeshi commented May 2, 2025

Description

According the documentation,

If you want to return errors with specific error codes, there is an easy way:

@Get("/users/:id")
getOne(@Param("id") id: number) {

    const user = this.userRepository.findOneById(id);
    if (!user)
        throw new NotFoundError(`User was not found.`); // message is optional

    return user;
}

Now, when user won't be found with requested id, response will be with http status code 404 and following content:

{
  "name": "NotFoundError",
  "message": "User was not found."
}

Source

Unfortunately, when I tried to throw the BadRequestError, I can not access to response data:

Image

According to response headers, the Content-Type has text/html; charset=utf-8 type:

Image

Same as browser developer tools can not parse it, the text() method of fetch API fails.

Minimal code-snippet showcasing the problem

import {
  Controller,
  Post,
  BadRequestError
} from "routing-controllers";


@Controller()
export default class SampleController {

  @Post("/api/sample")
  protected sampleHandler(): void {
    throw new BadRequestError("Sample");
  }

}

Expected behavior

The response with content-type: application/json; charset=utf-8 header and following content will be submitted to client:

{
  "name": "BadRequestError",
  "message": "Sample"
}

Actual behavior

The response has content-type: text/html; charset=utf-8 header and non-parseable content.

@TokugawaTakeshi TokugawaTakeshi added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels May 2, 2025
@attilaorosz
Copy link
Member

Could you try @JsonController instead of @Controller?

@TokugawaTakeshi
Copy link
Author

@attilaorosz

Thank you for the answer.

Could you try @JsonController instead of @Controller?

I have tried @JsonController , but nothing has changed.
Well, even it works, my controllers returns both JSON and HTML, so it was not the solution.l

I am using option classTransformer: false, maybe it is related?
My application will not work if I'll enable it.

@attilaorosz
Copy link
Member

I don't really understand how it could return both html and json. Could you setup a simple reproduction repo for this so I can check it?

@TokugawaTakeshi
Copy link
Author

@attilaorosz

Could you setup a simple reproduction repo for this so I can check it?

It will take some some to boil down my app which is production-ready, but if you need to for investigation, I'll prepare it.
Please keep this issue opened.

I don't really understand how it could return both html and json.

Simply if MVC application also has REST API.

@Controller
class BlogPostController {

  /* === MVC ======================== */
  @View("views/BlogPost.hbs")
  protected renderBlogPostPage(): Promise<BlogPost> {
     // ... Transactions with DB
     return {
        // ...
     }
  }

  /* === REST ======================== */
  protected addBlogPost(): Promise<void> {
    // ... Transactions with DB
    // Once done frontend can redirect to blog post page thus does not need the response data
  }

}

@TokugawaTakeshi
Copy link
Author

TokugawaTakeshi commented May 9, 2025

@attilaorosz

Sorry for keep you waiting.
Fortunately, the creating of reproduction have not took too much time, even I was not need to boil done my initial project.

Here is the reproduction:
https://github.com/TokugawaTakeshi/Issue-RoutingControllersErrorData

As you can see, there is still Content-Type: text/html; charset=utf-8 among the response headers while the response body is even not the HTML:

Image

Image

@attilaorosz
Copy link
Member

attilaorosz commented May 10, 2025

Ok I think I understand your problem now.
The thing is, if you don't use @JsonController, the response type will not be set to json. If you would like to have a mixed response type controller you can do it manually.

Keep your view methods html, so @Controller is sufficient.

For the json methods, inject @Res() into the method params, constuct your response as it was a normal express response, then return the res object from the method.

  @Get('/api/sample')
  protected sampleHandlerJson(@Res() res: Response) {
    res.status(404);
    res.json();

    return res;
  }

  @Get('/api/sample/working')
  protected sampleHandlerJsonWithoutError(@Res() res: Response) {
    res.json({myParam: 'myValue'});

    return res;
  }

@attilaorosz
Copy link
Member

Alternatively, if you only want to use json for errors, you can do this response handling in the error handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.
Development

No branches or pull requests

2 participants