Comments (17)
provide a code snippet of what you are doing
from routing-controllers.
Please find the following git repo with reproduceble code.
https://github.com/MContagious/routing-controller-sample
from routing-controllers.
what will happen if you remove @EmptyResultCode(404)
?
from routing-controllers.
Initially I dont have that annotation. Later I included to resolve that error but it is still throwing 404 error. But, The browser is getting the json response. Error is written in the server log.
from routing-controllers.
use new @OnUndefined
/ @OnNull
decorators to resolve this issue.
from routing-controllers.
This happening to me as well. I try to handle a file upload I see this in the console:
body-parser:json content-type "multipart/form-data; boundary=--------------------------042144984244033328614529" +977ms
body-parser:json skip parsing +0ms
morgan log request +977ms
POST /upload/photos 200 - ms - 14
finalhandler cannot 404 after headers sent +977ms
And it also happens when I implicitly return a value:
@Post('/photos')
async uploadPhotos() {
return { wee: 'wooo' };
}
In this case the console output is:
express:router dispatching POST /upload/photos +34s
express:router query : /upload/photos +0ms
express:router expressInit : /upload/photos +0ms
body-parser:json content-type "application/json" +34s
body-parser:json content-encoding "identity" +0ms
body-parser:json read body +0ms
body-parser:json parse body +1ms
body-parser:json parse json +0ms
express:router logger : /upload/photos +1ms
express:router jsonParser : /upload/photos +1ms
body-parser:json body already parsed +1ms
morgan log request +34s
POST /upload/photos 200 - ms - 34
finalhandler cannot 404 after headers sent +34s
Probably next()
gets called even after a route match?
from routing-controllers.
Probably next() gets called even after a route match?
yes, it is
from routing-controllers.
So is it an easy fix? I think it happens somewhere in the routing-controllers package. Or is it intentional?
from routing-controllers.
Or is it intentional?
yes next()
method call is intentional, because otherwise middleware that execute after your controllers wont work.
from routing-controllers.
Yes, but if I see correctly all we have to do is to register a special last middleware after registering the normal ones not?
I see you register them in index.ts
at here , isn't it enough to change this to something like
new RoutingControllers(driver)
.initialize()
.registerMiddlewares("before")
.registerControllers(controllerClasses)
.registerMiddlewares("after", middlewareClasses);
.registerFinalMiddleware(FinalMiddleware);
where final middleware looks something like:
import {ExpressMiddlewareInterface} from "../../src/driver/express/ExpressMiddlewareInterface";
import {Middleware} from "../../src/decorator/Middleware";
@Middleware({ type: "after" })
export class FinalMiddleware implements ExpressMiddlewareInterface {
use(request: any, response: any, next?: Function): any {
// next() not called here
}
}
and the registerFinalMiddleware
function looks something like:
registerFinalMiddleware(class: Function): this {
this.metadataBuilder
.buildMiddlewareMetadata([class])
.forEach(middleware => this.driver.registerMiddleware(middleware));
return this;
}
from routing-controllers.
Or we can just do
new RoutingControllers(driver)
.initialize()
.registerMiddlewares("before")
.registerControllers(controllerClasses)
.registerMiddlewares("after", [...middlewareClasses, FinalMiddleware]);
but then we still have to ensure metadata is already built for this class.
from routing-controllers.
Btw shouldn't we reopen this? Having "Cannot set headers after response is sent" errors for every request is not okay, and I believe using @OnUndefined
/ @OnNull
doesn't solve the problem, but my proposal does.
from routing-controllers.
Having "Cannot set headers after response is sent" errors for every request is not okay
right, its not okay. And I don't have such errors after every request. Can you show what are you doing that you have such error?
@Post('/photos')
async uploadPhotos() {
return { wee: 'wooo' };
}
This code should not give you such error. As I understood you have such error because of finalhandler
you are using, right? If yes, then why are you using it?
from routing-controllers.
As I understood you have such error because of finalhandler you are using, right? If yes, then why are you using it?
finalhandler
is a dependency of the express framework itself. It is called as a last middleware to set the status code to500
if you call next()
too many times.
On the user side it can be fixed with using a custom middleware:
import { Middleware, ExpressMiddlewareInterface } from "routing-controllers";
import { NextFunction, Request, Response } from 'express';
const debug = require('debug')('middleware:FinalMiddleware');
@Middleware({ type: "after" })
export class FinalMiddleware implements ExpressMiddlewareInterface {
use(req: Request, res: Response, next?: NextFunction): any {
debug('Final middleware reached!')
}
}
and loading it as the last one:
this.express = createExpressServer({
routePrefix: '',
middlewares: [CorsMiddleware, FinalMiddleware],
});
This code should not give you such error.
The only cause I can think of is that I am loading some vanilla express middleware this way:
this.express = createExpressServer({
routePrefix: '',
middlewares: [CorsMiddleware, FinalMiddleware],
});
this.express.use(logger('dev'));
this.express.use(bodyParser.json());
But it should still cause the error with the above solution if this would be the root of the error. So I don't have any idea how finalHandler
get reached. I dont call next()
anywhere in my code except in CorsMiddleware
which has the type before
from routing-controllers.
There is a next()
after each route execution, can your issue be because of #114 ?
from routing-controllers.
I don't think so because I have no specific route handlers for OPTION requests, I just early return with a 200 code and an empty response body in the CORS middleware (type: before) and I don't call next at all in that case so my routes are not reached.
from routing-controllers.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
from routing-controllers.
Related Issues (20)
- fix: global middlewares (re)registered each time useExpressServer is called HOT 3
- question: @Param not type casted HOT 21
- question: building the code looks for Koa, while I'm only using Express HOT 8
- fix: class-validator does not work on last version of RC HOT 9
- fix: <Injected Response object is undefined> HOT 1
- question: @Get path with literal and variable HOT 3
- feature: <how make sub folder controllers> how make sub folder controllers HOT 2
- fix: jsdoc for Put http method, it mentions POST http method
- fix: TypeDI do not inject service HOT 1
- Annotate return type of `createExpressServer` with more narrow type HOT 1
- `cors: true` causes "Cannot set headers after they are sent to the client" error HOT 3
- fix: Global middlewares are not used if route prefix doesn't start with a slash ("/")
- fix: TypeError this.targetType.toLowerCase is not a function HOT 3
- fix: import statements should not affect the route matching order
- Can we create multiple paths for the same controller function? HOT 7
- fix: CJS being imported instead of ESM when trying to load controllers from directory import HOT 4
- feature: Allow to use `app.use(createExpressRouter())` instead of `useExpressServer(app)` HOT 6
- question: Routes with path parameters continue middleware chain (but those without, don't)? HOT 5
- feature: Dynamic route HOT 4
- feature: Introduce Generics to CurrentUserChecker for Enhanced Type Safety HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from routing-controllers.