-
Notifications
You must be signed in to change notification settings - Fork 483
Handle 404 and 500 errors #667
Comments
I'm upvoting this one. |
Hi :). I have solved this in angular 4 using so called Here you can see my solution. https://github.com/kukjevov/ng-universal-demo/blob/mine/app/pages/notFound/notFound.component.ts Just before i render content to string i retrieve status code from service and then send it together with html and statusCode and process it in https://github.com/kukjevov/ng-universal-demo/blob/mine/server.js It is working. Maybe not best solution but working one :). But I am not using ngExpressEngine, but rendering result directly by myselft. |
Thank you @kukjevov that's one of the best ways to handle it that I'm aware of! |
I'm sorry to revisit an old issue, but I still quite haven't figured this one out. I can't seem to find the definition for As far as I understand this, there should be a way to manipulate the status code inside the ngExpressEngine, but I haven't figured out how that should be done. |
Hi i try to explain myself one more time :). To make it working you must implement following: StatusCodeService import {Injectable} from '@angular/core';
/**
* Service used for transfering http status code for response
*/
@Injectable()
export class StatusCodeService
{
//######################### private fields #########################
/**
* Current status code
*/
private _statusCode?: number;
//######################### public properties #########################
/**
* Gets current status code
*/
public get statusCode(): number | null | undefined
{
return this._statusCode;
}
//######################### public methods #########################
/**
* Sets current status code
* @param {number} code Status code value that will be set
*/
public setStatusCode(code?: number)
{
this._statusCode = code;
}
} You need to create your own method for rendering to string see https://github.com/angular/angular/blob/master/packages/platform-server/src/utils.ts modify function at line 37 function _render<T>(
platform: PlatformRef, moduleRefPromise: Promise<NgModuleRef<T>>): Promise<{html: string, statusCode?: number}> {
return moduleRefPromise.then((moduleRef) => {
const transitionId = moduleRef.injector.get(ɵTRANSITION_ID, null);
if (!transitionId) {
throw new Error(
`renderModule[Factory]() requires the use of BrowserModule.withServerTransition() to ensure
the server-rendered app can be properly bootstrapped into a client app.`);
}
const applicationRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
return toPromise
.call(first.call(filter.call(applicationRef.isStable, (isStable: boolean) => isStable)))
.then(() => {
let statusCodeService = moduleRef.injector.get(StatusCodeService);
let statusCode: number | null = null;
if(statusCodeService)
{
statusCode = statusCodeService.statusCode;
}
const output = {html: platform.injector.get(PlatformState).renderToString(), statusCode};
platform.destroy();
return output;
});
});
} That means that method used for rendering to string returns object which contains html as string and status code as number. You will use this in your server, does not matter what kind of server (nodejs, .net) to set response status code and content. For example if you use Connect nodejs server. res.setHeader('Content-Type', 'text/html');
if(succ.statusCode)
{
res.statusCode = succ.statusCode;
}
res.end(err || succ.html); Where Then when you use I hope this helps. |
@kukjevov after a long time I finally got this to work. Thank you so much! you are a gentleman and a scholar. |
A simple service using ngExpressEngine response: being used here: |
A very simple solution is to provide response object, under some injection token (e.g. angular universal's |
@alirezamirian that is the best solution so far. Since I just stumbled upon this problem myself, I recorded my procedure in a blog post: https://blog.thecodecampus.de/angular-universal-handle-404-set-status-codes/ |
And this is how you apply @CanKattwinkel’s howto on the latest v6 app.engine('html', (_, options, callback) =>
ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP),
{
provide: REQUEST,
useValue: options.req,
},
{
provide: RESPONSE,
useValue: options.req.res,
},
],
})(_, options, callback)
) |
@msklvsk Thanks for saving my evening. |
When I send the 404 status, my express server just shows a |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Note: for support questions, please use one of these channels: https://github.com/angular/universal/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports. Also, Preboot has moved to https://github.com/angular/preboot - please make preboot-related issues there.
Do you want to request a feature or report a bug?
Request a feature
What is the current behavior?
There's currently no way I can find to make sure the server responds with an HTTP status code 404 when I need to.
Furthermore, when there's an error the server currently refuses the connection.
What is the expected behavior?
There should be a way to send responses with HTTP status 404.
Additionally, there should be a way to handle errors and send responses with HTTP status 500.
What is the motivation / use case for changing the behavior?
When application logic determines there should be a 404 error (for instance, having a route for
{ path: 'clients/:client-id' }
, doing an API request and finding the client ID requested doesn't exist) you should respond with a 404 page. Currently, you can handle this in your application and show a 404 page, but it'll be served with a 200 status code.Additionally, there should be a way to handle any error and show the user a 500 error page, served with the correct status code.
The text was updated successfully, but these errors were encountered: