phonegap / phonegap-cli

PhoneGap and PhoneGap/Build command-line interface
Apache License 2.0
491 stars 156 forks source link

`serve` crashes if URL being proxied is non-existent #668

Open kaka-go opened 7 years ago

kaka-go commented 7 years ago

PhoneGap CLI, node & npm versions

$ phonegap -v
6.3.4
$ node -v
v6.9.1
$ npm -v
3.10.8

Expected Behaviour

Request the API successfully without error.

Actual Behaviour

It irregularly happens. A proxy error was thrown, then phonegap died.

Steps to Reproduce

Mostly the problem happens when auto refresh is working after some file are changed.

Sample Code that illustrates the problem

Error messages

[phonegap] 200 http://myapp.com/api/get_something
[phonegap] [console.log] [object XMLHttpRequest]
[phonegap] Proxy error for url: http://myapp.com/api/get_something_else undefined
_http_server.js:192
    throw new RangeError(`Invalid status code: ${statusCode}`);
    ^

RangeError: Invalid status code: 0
    at ServerResponse.writeHead (_http_server.js:192:11)
    at ServerResponse.res.writeHead (/usr/local/lib/node_modules/phonegap/node_modules/connect/lib/patch.js:85:22)
    at error (/usr/local/lib/node_modules/phonegap/node_modules/connect-phonegap/lib/middleware/proxy.js:38:25)
    at ClientRequest.proxyError (/usr/local/lib/node_modules/phonegap/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:137:9)
    at emitOne (events.js:101:20)
    at ClientRequest.emit (events.js:188:7)
    at Socket.socketCloseListener (_http_client.js:286:9)
    at emitOne (events.js:101:20)
    at Socket.emit (events.js:188:7)
    at TCP._handle.close [as _onclose] (net.js:498:12)
surajpindoria commented 7 years ago

Hi @edward9145,

Can you provide some sample code that you are using when you run into this error?

kaka-go commented 7 years ago

@surajpindoria I used the $$.get and $$.post method in Framework7 library to do the ajax request. https://framework7.io/docs/dom.html#shorthand-methods

Here is the sample code.

index.html

  <script type="text/javascript" src="cordova.js"></script>
  <script type="text/javascript" src="js/web_socket.js"></script>
  <!-- Path to Framework7 Library JS-->
  <script type="text/javascript" src="js/framework7.min.js"></script>
  <script type="text/javascript" src="js/myapp.js"></script>

myapp.js

// Initialize your app
var myApp = new Framework7();

// Export selectors engine
var $$ = Dom7;

$$.get("http://myapp.com/api/test", {param1: "value1"}, function(res) {
   var data = JSON.parse(res);
   // handle data ...
});

hope this would be helpful

surajpindoria commented 7 years ago

Are you testing on the browser or on a device? I just tried on both, it doesn't work on the browser but on the device it does.

kaka-go commented 7 years ago

It should happen both on browser and device. Usually, I use the browser to debug the app.

Maybe it's caused by too many API requests at the same time.

Actually, when I debug the app with phonegap-desktop, the "Proxy Error" problem never happened. I guess maybe the code of desktop catch the error and restart the proxy server.

norbertsongin commented 7 years ago

I'm having this problem currently. It started after I deleted cookies from local app served with phonegap serve. Phonegap crashes shortly after going to localhost:3000 in browser with following logs

[phonegap] [console.error] Missing Command Error
[phonegap] Proxy error for url: blob:http://localhost:3000/74f5a5a8-845b-4b5a-8fd2-33c67ed1347e undefined
_http_server.js:192
    throw new RangeError(`Invalid status code: ${statusCode}`);
    ^

RangeError: Invalid status code: 0
    at ServerResponse.writeHead (_http_server.js:192:11)
    at error (C:\Users\Norbert\AppData\Roaming\nvm\v6.8.1\node_modules\phonegap\node_modules\connect-phonegap\lib\middleware\proxy.js:38:25)
    at ClientRequest.proxyError (C:\Users\Norbert\AppData\Roaming\nvm\v6.8.1\node_modules\phonegap\node_modules\http-proxy\lib\http-proxy\passes\web-incoming.js:146:9)
    at emitOne (events.js:101:20)
    at ClientRequest.emit (events.js:188:7)
    at Socket.socketErrorListener (_http_client.js:310:9)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at connectErrorNT (net.js:1020:8)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

I reinstalled project dependencies and even phonegap, but nothing seems to work. Any suggestions?

light commented 7 years ago

This error happens when the proxied server refuses the connection. There is no numeric HTTP error code then, but instead 'ECONNREFUSED', which is passed as-is to node's HTTP server which interprets it as '0', causing the error. The proxy should probably send an HTTP 502 or 503 status code instead.

filmaj commented 7 years ago

For the record, #652 tracks the fact that proxying legitimate URLs is broken for the browser platform.

I am totally able to reproduce this error by issuing a garbage XHR request to a non-existent domain in a phonegap project with the browser platform added being served.

E.g. with an XHR set to fire off against http://asdkjhsd.com/, I get the following in phonegap -d serve output + crash:

[phonegap] Proxy error for url: http://asdkjhsd.com/ undefined
_http_server.js:192
    throw new RangeError(`Invalid status code: ${statusCode}`);
    ^

RangeError: Invalid status code: 0
    at ServerResponse.writeHead (_http_server.js:192:11)
    at error (/Users/maj/src/phonegap-cli/node_modules/connect-phonegap/lib/middleware/proxy.js:37:25)
    at ClientRequest.proxyError (/Users/maj/src/phonegap-cli/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:146:9)
    at emitOne (events.js:101:20)
    at ClientRequest.emit (events.js:188:7)
    at Socket.socketErrorListener (_http_client.js:309:9)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at connectErrorNT (net.js:1025:8)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
filmaj commented 7 years ago

OK, I've filed phonegap/connect-phonegap#191 which should fix the underlying issue. At that point we'll need to bump the dependency in this project and we should be good to go.