Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Server side error. Promise uncaught? #1063

Closed
tomskip123 opened this issue Sep 4, 2018 · 12 comments
Closed

Server side error. Promise uncaught? #1063

tomskip123 opened this issue Sep 4, 2018 · 12 comments

Comments

@tomskip123
Copy link

tomskip123 commented Sep 4, 2018

Bug Report

What is the expected behavior?

server side to execute http requests and render lazy loaded modules as expected...
i've gone through all my http promises and caught them but the line number references seem
very early on in server.js which is angular code? anyone know whats going on?

server side throws error shown bellow then the client is sent and rendered normally on the client with no errors.

ERROR { Error: Uncaught (in promise): Error
    at resolvePromise (root\to\workspace\dist\server.js:1040:31)
    at resolvePromise (root\to\workspace\dist\dist\server.js:997:17)
    at root\to\workspace\dist\dist\server.js:1099:17
    at ZoneDelegate.invokeTask (root\to\workspace\dist\dist\server.js:647:31)
    at Object.onInvokeTask (root\to\workspace\dist\dist\server.js:7804:33)
    at ZoneDelegate.invokeTask (root\to\workspace\dist\dist\server.js:646:36)
    at Zone.runTask root\to\workspace\dist\dist\server.js:414:47)
    at drainMicroTaskQueue root\to\workspace\dist\dist\server.js:821:35)
    at ZoneTask.invokeTask (root\to\workspace\dist\dist\server.js:726:21)
    at Server.ZoneTask.invoke (root\to\workspace\dist\dist\server.js:711:48)
  rejection: [Error],
  promise: ZoneAwarePromise { __zone_symbol__state: 0, __zone_symbol__value: [Error] },
  zone:
   Zone {
     _properties: { isAngularZone: true },
     _parent:
      Zone {
        _properties: {},
        _parent: null,
        _name: '<root>',
        _zoneDelegate: [Object] },
     _name: 'angular',
     _zoneDelegate:
      ZoneDelegate {
        _taskCounts: [Object],
        zone: [Circular],
        _parentDelegate: [Object],
        _forkZS: null,
        _forkDlgt: null,
        _forkCurrZone: [Object],
        _interceptZS: null,
        _interceptDlgt: null,
        _interceptCurrZone: [Object],
        _invokeZS: [Object],
        _invokeDlgt: [Object],
        _invokeCurrZone: [Circular],
        _handleErrorZS: [Object],
        _handleErrorDlgt: [Object],
        _handleErrorCurrZone: [Circular],
        _scheduleTaskZS: [Object],
        _scheduleTaskDlgt: [Object],
        _scheduleTaskCurrZone: [Circular],
        _invokeTaskZS: [Object],
        _invokeTaskDlgt: [Object],
        _invokeTaskCurrZone: [Circular],
        _cancelTaskZS: [Object],
        _cancelTaskDlgt: [Object],
        _cancelTaskCurrZone: [Circular],
        _hasTaskZS: [Object],
        _hasTaskDlgt: [Object],
        _hasTaskDlgtOwner: [Circular],
        _hasTaskCurrZone: [Circular] } },
  task:
   ZoneTask {
     _zone:
      Zone {
        _properties: [Object],
        _parent: [Object],
        _name: 'angular',
        _zoneDelegate: [Object] },
     runCount: 0,
     _zoneDelegates: null,
     _state: 'notScheduled',
     type: 'microTask',
     source: 'Promise.then',
     data: ZoneAwarePromise { __zone_symbol__state: 0, __zone_symbol__value: [Error] },
     scheduleFn: undefined,
     cancelFn: null,
     callback: [Function],
     invoke: [Function] } }

main.ts

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

import {AppModule} from './app/app.module';
import {environment} from './environments/environment';

if (environment.production) {
    enableProdMode();
}

document.addEventListener('DOMContentLoaded', () => {
    platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .catch(err => console.log(err));
});

server.ts

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {enableProdMode} from '@angular/core';
import * as express from 'express';
import * as csp from 'helmet-csp';
import * as helmet from 'helmet';
import {join} from 'path';
// Express Engine
// Import module map for lazy loading
import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';
import {ngExpressEngine} from '@nguniversal/express-engine';

import {REQUEST, RESPONSE} from '@nguniversal/express-engine/tokens';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();
const proxy = require('http-proxy-middleware');

// CHANGE FOR DEV (npm run server)

const apiLB = process.env.API_URI || 'http://localhost:4002';

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');

// * NOTE :: leave this as require() since this files is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');

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)
);

// proxy requests to the api lb for api requests
app.use('/api', proxy({
    target: apiLB,
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

app.use(helmet());

app.use(helmet.referrerPolicy({
    policy: 'same-origin'
}));

app.disable('x-powered-by');

// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), {
    maxAge: '1y'
}));

// ALl regular routes use the Universal engine
app.get('*', (req, res) => {
    res.render('index', {req});
});

// Start up the Node server
app.listen(PORT, () => {
    console.log(`Node Express server listening on http://localhost:${PORT}`);
});

it may have something to do with lazy loading?

What modules are related to this issue?

- [ ] aspnetcore-engine
- [ ] common
- [ *] express-engine
- [ ] hapi-engine
- [ *] module-map-ngfactory-loader

Environment:

@nguniversal versions

  • express-engine:
  • module-map-ngfactory-loader:
Angular CLI: 6.1.5
Node: 8.11.4
OS: win32 x64
Angular: 6.1.6
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.7.5
@angular-devkit/build-angular     0.7.5
@angular-devkit/build-optimizer   0.7.5
@angular-devkit/build-webpack     0.7.5
@angular-devkit/core              0.7.5
@angular-devkit/schematics        0.7.5
@angular/cli                      6.1.5
@ngtools/webpack                  6.1.5
@schematics/angular               0.7.5
@schematics/update                0.7.5
rxjs                              6.3.2
typescript                        2.9.2
webpack                           4.9.2

Windows (10)

@tomskip123
Copy link
Author

so i saw this comment: #741 (comment)

and enabled source maps. and the issue has magically disappeared. so whoop whoop.

This isn't in the docs or anything so i could't find any info anywhere. but yeah issue solved :)

@Webjin
Copy link

Webjin commented Dec 14, 2018

Still looking to solve this, tried enabling the sourcemaps, to no avail unfortunatly

@freefred81
Copy link

Hi .. same problem here .. Angular 7 + UNIVERSAL ... same error
any news ?

@tomskip123
Copy link
Author

could you post a little more info? preferably your angular.json, what version are you using, server.ts?

@freefred81
Copy link

freefred81 commented Apr 8, 2019

Hi .. sorry for delay ..

Here are my files:

============================================
package.json:

============================================

{
"name": "sp",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:ssr": "node dist/server",
"build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
"build:client-and-server-bundles": "ng build --prod && gulp && ng run sp:server:production && cp .runtimeconfig.json dist",
"run-universal": "npm run build:ssr && npm run serve:ssr",
"deploy": "rimraf functions/dist && rimraf public && mkdir public && npm run build:ssr && cp -a dist functions && cp -a functions/dist/browser/. public && mv public/index.html public/index2.html && firebase deploy"
},
"private": true,
"dependencies": {
"@agm/core": "^1.0.0-beta.5",
"@angular/animations": "~7.2.0",
"@angular/cdk": "~7.3.4",
"@angular/common": "~7.2.0",
"@angular/compiler": "~7.2.0",
"@angular/core": "~7.2.0",
"@angular/forms": "~7.2.0",
"@angular/http": "~7.2.0",
"@angular/material": "^7.3.4",
"@angular/platform-browser": "~7.2.0",
"@angular/platform-browser-dynamic": "~7.2.0",
"@angular/platform-server": "~7.2.0",
"@angular/pwa": "^0.12.4",
"@angular/router": "~7.2.0",
"@angular/service-worker": "~7.2.0",
"@nguniversal/express-engine": "^7.1.1",
"@nguniversal/module-map-ngfactory-loader": "^7.1.1",
"@nicky-lenaers/ngx-scroll-to": "^2.0.0",
"autoprefixer": "^9.5.0",
"classlist.js": "^1.1.20150312",
"core-js": "^2.5.4",
"express": "^4.15.2",
"hammerjs": "^2.0.8",
"jquery": "^3.3.1",
"localstorage-polyfill": "^1.0.1",
"ng-lazyload-image": "^5.0.0",
"ngx-slick": "^0.2.1",
"ngx-slick-carousel": "^0.4.4",
"postcss-cli": "^6.1.2",
"rxjs": "~6.3.3",
"slick-carousel": "^1.8.1",
"tslib": "^1.9.0",
"web-animations-js": "^2.3.1",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.13.0",
"@angular/cli": "~7.3.5",
"@angular/compiler-cli": "~7.2.0",
"@angular/language-service": "~7.2.0",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"ts-loader": "^5.2.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.2.2",
"webpack-cli": "^3.1.0",
"ws": "^6.2.0",
"xmlhttprequest": "^1.8.0",
"gulp": "^4.0.0",
"gulp-htmlmin": "^5.0.1",
"gulp-imagemin": "^5.0.3"
}
}

=========================================

angular.json :

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sp": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"style": "sass",
"skipTests": true
},
"@schematics/angular:class": {
"skipTests": true
},
"@schematics/angular:directive": {
"skipTests": true
},
"@schematics/angular:guard": {
"skipTests": true
},
"@schematics/angular:module": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
},
"@schematics/angular:service": {
"skipTests": true
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.json"
],
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"node_modules/slick-carousel/slick/slick.scss",
"node_modules/slick-carousel/slick/slick-theme.scss",
"src/styles.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/slick-carousel/slick/slick.min.js"
],
"es5BrowserSupport": true
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "none",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": true,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
],
"serviceWorker": true,
"ngswConfigPath": "src/ngsw-config.json"
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sp:build"
},
"configurations": {
"production": {
"browserTarget": "sp:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sp:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.json"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"/node_modules/"
]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
}
}
},
"sp-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sp:serve"
},
"configurations": {
"production": {
"devServerTarget": "sp:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"/node_modules/"
]
}
}
}
}
},
"defaultProject": "sp"
}

==========================================
server.ts

// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import 'localstorage-polyfill'

import { enableProdMode } from '@angular/core';

import * as express from 'express';

import { join } from 'path';

const env = require('./.runtimeconfig.json');
console.log('env: ' + env);

//FIX FOR localstorage
global['localStorage'] = localStorage;
global['sessionStorage'] = localStorage;
(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;

// Faster server renders w/ Prod mode (dev mode never needed)
//enableProdMode();

// Express server
const app = express();

const PORT = env.platform.port || 3000;
const DIST_FOLDER = join(process.cwd(), 'dist');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

app.engine('html', (_, options, callback) => {
let engine = ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: 'host', useFactory: () => options.req.get('host'), deps: [] }
]
});

engine(_, options, callback)
});

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

// TODO: implement data requests securely
app.get('/api/*', (req, res) => {
res.status(404).send('data requests are not supported');
});

// Server static files from /browser
app.get('.', express.static(join(DIST_FOLDER, 'browser')));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render('index', { req });
});

console.log(env.platform);
//TODO --> DECOMMENT IF NOT FIREABSE FUNCTION
if (env && env.platform && !env.platform.isfirebase) {
console.log('here');
// Start up the Node server
app.listen(PORT, () => {
console.log(Node server listening on http://localhost:${PORT});
});
}

exports.app = app;

============================================

main.ts

import 'hammerjs';
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { environment } from './environments/environment';
import { AppBrowserModule } from './app/app-browser.module';

if (environment.production) {
enableProdMode();
}

document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppBrowserModule)
.then(() => {
if ('serviceWorker' in navigator && environment.production) {
navigator.serviceWorker.register('/ngsw-worker.js', {
updateViaCache: 'none'
}).then((sw) => {
sw.update();
});
}
})
.catch(err => console.error('errfromMAin :' + err));
});

============================================
main.server.ts

import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';

if (environment.production) {
enableProdMode();
}

export { AppServerModule } from './app/app.server.module';

============================================

============================================
app.module.browser.ts

import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppModule} from './app.module';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

@NgModule({
imports: [
BrowserAnimationsModule,
AppModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
],
bootstrap: [AppComponent]
})
export class AppBrowserModule { }

============================================

============================================
app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
// The AppServerModule should import your AppModule followed
// by the ServerModule from @angular/platform-server.
ServerModule,

AppModule,
ModuleMapLoaderModule // <-- *Important* to have lazy-loaded routes work

],
// Since the bootstrapped component is not inherited from your
// imported AppModule, it needs to be repeated here.
bootstrap: [AppComponent],
})
export class AppServerModule { }

============================================

============================================
app.module.ts

import { BrowserModule, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { NgModule, LOCALE_ID } from '@angular/core';
import { AppRoutingModule } from './app.routing';
import { AppComponent } from './app.component';
import { FullLayoutComponent } from './layouts/full-layout/full-layout.component';
import { NavBarComponent } from './components/nav-bar/nav-bar.component';
import { FooterComponent } from './components/footer/footer.component';
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { HttpClientModule } from '@angular/common/http';
import { MatExpansionModule } from '@angular/material/expansion';
import { GestureConfig } from '@angular/material/core';
import { registerLocaleData, CommonModule } from '@angular/common';
import localeIt from '@angular/common/locales/it';

registerLocaleData(localeIt, 'it');

@NgModule({
declarations: [
AppComponent,
FullLayoutComponent,
NavBarComponent,
FooterComponent
],
imports: [
CommonModule,
HttpClientModule,
BrowserModule.withServerTransition({ appId: 'serverApp' }),
AppRoutingModule,
MatSnackBarModule,
MatMenuModule,
MatButtonModule,
MatExpansionModule

],
providers: [
{ provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig },
{ provide: LOCALE_ID, useValue: "it" },
],
bootstrap: [AppComponent]
})
export class AppModule { }

============================================

One more info .. the app is working (even the SSR) but it throws the error exception (it still work after .. but it's not so nice)...thnx for your help!!!

@tomskip123
Copy link
Author

tomskip123 commented Apr 8, 2019

Can you try putting outputHashing to "all" and changing vendorChunks to false in angular.json.

not sure but i think the unresolved promise error is something to do with the server failing to get the lazyloaded module on the server.

@freefred81
Copy link

Hi .. I've just tried to outputHashing to "all" .. ok now i try to change vendorChunks ..

and sorry for the typo .. but in the app.module.ts THERE IS BrowserModule.withServerTransition({ appId: 'serverApp' }),

THNX!!! ;)

@freefred81
Copy link

Hi .. new update .. now it works perfect .. the prob (i think) was related to the Lazy loaded Routes ... there were NO 'normal' route (ALL routes were lazy loaded) .. now we have one deafult eager route/component ..and it looks ok ... THNX for you support!!!!

@BruneXX
Copy link

BruneXX commented Aug 30, 2019

Hi @freefred81 please can you let me know, what change have you performed to make this work?
I've changed sourceMap to true but the error is still there.. can you share more info about your workaround? thanks!

@freefred81
Copy link

Hi Brune ... it's a long time from this post ..and a loto of version of angular has passed .... BUT from what i remember my problem was:

In my project there were not 1 normal root (not lazy loaded) ..all root were lazy loaded ... try to change the first rott (your default root) to a normal one

@BruneXX
Copy link

BruneXX commented Aug 30, 2019

Hi @freefred81 yeah! The first thing I've tried was revert the routes to it's initial state but in my case wasn't work, I had to revert the entire app.module and it started to work again, anyway, I'll review one by one my modules in order to find the culprit.
Thanks for your quick reply it was very helpful. :)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants