angular: Universal not rendering due to 'Http failure response for (unknown url): 0 Unknown Error',

I did at one point have ssr working but somewhere along the line it’s broken and I just can’t find what’s causing the error. There are no errors client side and it renders fine but server side I get the following error which is preventing it rendering server side.

My issue is that it’s a large app I a just can’t pinpoint where the issue is.

HttpErrorResponse {
  headers: HttpHeaders { normalizedNames: Map {}, lazyUpdate: null, headers: Map {} },
  status: 0,
  statusText: 'Unknown Error',
  url: null,
  ok: false,
  name: 'HttpErrorResponse',
  message: 'Http failure response for (unknown url): 0 Unknown Error',
  error:
   ProgressEvent {
     type: 'error',
     target:
      XMLHttpRequest {
        onloadstart: null,
        onprogress: null,
        onabort: null,
        onerror: null,
        onload: null,
        ontimeout: null,
        onloadend: null,
        _listeners: [Object],
        onreadystatechange: null,
        _anonymous: undefined,
        readyState: 4,
        response: null,
        responseText: '',
        responseType: 'text',
        responseURL: '',
        status: 0,
        statusText: '',
        timeout: 0,
        upload: [Object],
        _method: 'GET',
        _url: [Object],
        _sync: false,
        _headers: [Object],
        _loweredHeaders: [Object],
        _mimeOverride: null,
        _request: null,
        _response: null,
        _responseParts: null,
        _responseHeaders: null,
        _aborting: null,
        _error: null,
        _loadedBytes: 0,
        _totalBytes: 0,
        _lengthComputable: false,
        withCredentials: true },
     currentTarget:
      XMLHttpRequest {
        onloadstart: null,
        onprogress: null,
        onabort: null,
        onerror: null,
        onload: null,
        ontimeout: null,
        onloadend: null,
        _listeners: [Object],
        onreadystatechange: null,
        _anonymous: undefined,
        readyState: 4,
        response: null,
        responseText: '',
        responseType: 'text',
        responseURL: '',
        status: 0,
        statusText: '',
        timeout: 0,
        upload: [Object],
        _method: 'GET',
        _url: [Object],
        _sync: false,
        _headers: [Object],
        _loweredHeaders: [Object],
        _mimeOverride: null,
        _request: null,
        _response: null,
        _responseParts: null,
        _responseHeaders: null,
        _aborting: null,
        _error: null,
        _loadedBytes: 0,
        _totalBytes: 0,
        _lengthComputable: false,
        withCredentials: true },
     lengthComputable: false,
     loaded: 0,
     total: 0 } }

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 18

Most upvoted comments

What was the solution?

If you used self sign cert , the problem is the Angular Universal used Express and the security validate the ssl certification to the server , i used a self sign ssl , the solution is add the env NODE_TLS_REJECT_UNAUTHORIZED=0 to disable the verification SSL in NodeJs , warning this env is only in dev , in production is so risky

So what was the solution?

Here is how I found and fixed my issue:

My angular app is making local requests to the API in a different container ( http://localhost:xxxx ), but the docker container does not have access to the localhost network, resulting all API requests made to localhost by the server to return Http failure response for (unknown url): 0 Unknown Error , although the client requests are succeeding since the requests are made by the client.

In order to allow access to the local network you could just simply replace localhost with docker.for.mac.localhost (if you are using Docker for Mac, more info here : https://stackoverflow.com/a/43541732 )

TL;DR;

My flow consists of an Angular 6 app that uses resolvers to fetch data from a Wordpress API backend. The API url is different for development and production, so they are stored in separate environment files. Everything was working correctly on the client side, except at some point I realized that the SSR version is broken with the error from this issue title.

Since I had no clue where the error was coming from ( other than it was a http error ) I started by adding enableTracing: true to the Routing module and logging the requests in the HttpInterceptor. At that point I realized that even though I’m passing the --prod flag to ng build command, the server is making requests to the dev api url, while the client is correctly making requests to the prod api url. Strange, right?

After a few Google searches I found out that for the server to use the prod environment file ( same as client ) I need to pass the environment name to the ng run server command and add the production configuration to server in angular.json.

package.json "build-production:ssr": "ng build --prod && ng run site:server:production && npm run webpack:server",

angular.json

...
"server": {
	"builder": "@angular-devkit/build-angular:server",
	"options": {
		"outputPath": "dist/site-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"
			}]
		}
	}
}
...

Although this did not actually fix my issue, it made me realize how different the client and the server version of the same Angular application behaves and I was now able to the point the server to the production api url ( remote host ) and the SSR worked perfectly.

I now realized that the culprit has to be the locally api url ( http://localhost:xxxx/wp ). But how? I can log into the angular container and ping to localhost. What I realized only after a few more searches about docker containers is that the container cannot actually access the host and the ping actually went to the container. Gotcha!

Now I just needed to find a way for the angular container to access the api container. After a bit of research I found out that this can be done in multiple ways ( changing the network mode to host, creating an alias for the service network ) but I ended up with the easiest way which was to replace localhost with docker.for.mac.localhost which actually alows access for the container to the localhost network. ( https://stackoverflow.com/a/43541732 )

No, in my case there were two things. First, a call to function next() of express after the response was sent. And the second, a problem with the timeout in the configuration of the nginx that is serving the web (i’m using docker).

Hi guys,

I am not an expert but I think it is a CORS issue.