-
Notifications
You must be signed in to change notification settings - Fork 100
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
Can't set headers after they are sent. #255
Comments
We are also having this issue. It appears to only affect the last listed method in the controller class. I have found 2 workarounds but these go against the documentation of calling Workaround 1 (throw the error, seems a bit pointless try/catch to throw, but you may want to manipulate the error before you send it up):
Workaround 2 (utilise the Promises):
We haven't been able to figure out where the problem lies but it could be something to do with the decorators. |
@PodaruDragos I have very recently been added as maintainer and I am going to start working through the backlog |
Will there be an actual solution? I found that throwing an error works fine but not calling next |
Any update on this? The error handler doesn't seems to be working for me too. |
I'm having the same issue. I have this configuration to handle some method error with
The error in the console is |
I'm having a super weird issue as well with this... To give some context, This is my implementation of overriding the default error handler:
I have the following endpoint, let's call it
and then just below I have this empty endpoint, let's call this
If I have both As soon as I remove
I have no idea what is happening... |
I confirm the reports from @nref-dan and @Mannydheer Would be great to see some updates on this problem |
The Real Issue & SolutionThis issue is quite straightforward to resolve but comes with a philosophical twist. I tackled this in the ExpressoTS Framework, where you can seamlessly use hbs, ejs, express-handlebars, etc. While I could submit a PR, I’ve chosen not to—this is more of a philosophical battle I’d prefer to avoid. The IssueIn Express.js, if you don’t explicitly end the response (by calling methods like app.get("/", (req, res) => {
return;
}); In The idea behind automatically handling undefined return values with a 204 No Content status in inversify-express-utils is to prevent this hanging by default. There are few issues with his approach in terms of logic, and the way that the metadata is being handle to distinguish what is The file and method responsible for generating this situation is Here is the code: private handlerFactory(
controllerName: string,
key: string,
parameterMetadata: ParameterMetadata[],
): RequestHandler {
return async (
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const args = this.extractParameters(req, res, next, parameterMetadata);
const httpContext = this._getHttpContext(req);
httpContext.container.bind<HttpContext>(TYPE.HttpContext)
.toConstantValue(httpContext);
// invoke controller's action
const value = await (httpContext.container.getNamed<Controller>(
TYPE.Controller,
controllerName,
)[key] as ControllerHandler)(...args);
if (value instanceof HttpResponseMessage) {
await this.handleHttpResponseMessage(value, res);
} else if (instanceOfIHttpActionResult(value)) {
const httpResponseMessage = await value.executeAsync();
await this.handleHttpResponseMessage(httpResponseMessage, res);
} else if (value instanceof Function) {
value();
} else if (!res.headersSent) {
if (value === undefined) {
res.status(204);
}
res.send(value);
}
} catch (err) {
next(err);
}
};
} When you use if (value === undefined) {
res.status(204);
}
res.send(value); SOLUTION Option 1 - Remove the "Falsey" validation and make sure that the private handlerFactory(
controllerName: string,
key: string,
parameterMetadata: ParameterMetadata[],
): RequestHandler {
return async (
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const args = this.extractParameters(req, res, next, parameterMetadata);
const httpContext = this._getHttpContext(req);
httpContext.container.bind<HttpContext>(TYPE.HttpContext)
.toConstantValue(httpContext);
// invoke controller's action
const value = await (httpContext.container.getNamed<Controller>(
TYPE.Controller,
controllerName,
)[key] as ControllerHandler)(...args);
if (value instanceof HttpResponseMessage) {
await this.handleHttpResponseMessage(value, res);
} else if (instanceOfIHttpActionResult(value)) {
const httpResponseMessage = await value.executeAsync();
await this.handleHttpResponseMessage(httpResponseMessage, res);
} else if (value instanceof Function) {
value();
} else if (!res.headersSent) {
if (value !== undefined) {
res.send(value);
}
}
} catch (err) {
next(err);
}
};
} Secret sauce is right here in case you haven't see it } else if (!res.headersSent) {
if (value !== undefined) {
res.send(value);
} Option 2 - Make sure Final considerations If you decide to clone and build the lib by yourself, with the fix I use, pay attention to one particular test case in the it('should work for controller methods who\'s return value is falsey', done => {
@controller('/user')
class TestController {
@httpDelete('/')
public async delete(): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, 100));
}
}
server = new InversifyExpressServer(container);
void supertest(server.build())
.delete('/user')
.expect(204, '', done);
});
}); I hope this sheds some light on the final solution for those trying to use render engines with |
Hi. I decided to try an example. But on the request I get 204 code and an error in the logs. How I understand it before my error handler, some other one works.
The text was updated successfully, but these errors were encountered: