pouchdb / pouchdb

:kangaroo: - PouchDB is a pocket-sized database.
https://pouchdb.com/
Apache License 2.0
16.87k stars 1.47k forks source link

Error 500 with CORS warning #4643

Closed simonaberry closed 8 years ago

simonaberry commented 8 years ago

I am getting repetitive 500 errors (v5.1.0) and would appreciate some guidance on how to debug further.

Uncaught (in promise) e
error: true
message: "Database encountered an unknown error"
name: "unknown_error"
result: Object
doc_write_failures: 0
docs_read: 0
docs_written: 0
end_time: Tue Dec 08 2015 21:00:53 GMT+0200 (SAST)
errors: Array[1]...
ok: false
start_time: Tue Dec 08 2015 20:14:09 GMT+0200 (SAST)
status: "aborting"
status: 50

followed by a warning

PouchDB: the remote database may not have CORS enabled.If not please enable CORS: http://pouchdb.com/errors.html#no_access_control_allow_origin_header

but I definitely have cors enabled

curl --user XXX:XXX xxxx.cloudant.com/_api/v2/user/config/cors 
{
  "enable_cors": true, 
  "allow_credentials": true, 
  "origins": [
    "*"
  ]
}

this happens periodically, but especially when offline. I am canceling the sync as follows when offline is detected:

// on startup / online detected:
sync.company = db.sync(companyUrl, {live: true, retry: true})...

// if offline detected
console.log('offline detected - stopping sync');
if (sync.company) sync.company.cancel();

but am also seeing this error

offline detected - stopping sync
TypeError: o.company.cancel is not a function
    at e (vendor.js:62)
    at Object.fn (vendor.js:62)
    at n.$digest (vendor.js:5)
    at n.$apply (vendor.js:5)

(code has been minified)

inspecting the sync.company object i see it is a promise.... but the docs show that you should be able to call cancel() ??

http://pouchdb.com/api.html#sync

not sure if the sync cancel is in any way related to the 500 error, but thought it would be worth mentioning

simonaberry commented 8 years ago

so figured out the cancel()/promise issue.... the docs say

var sync = PouchDB.sync('mydb', 'http://localhost:5984/mydb', {
  live: true,
  retry: true
}).on('change', function (info) {
  // handle change
}).on('paused', function () {
  // replication paused (e.g. user went offline)
}).on('active', function () {
  // replicate resumed (e.g. user went back online)
}).on('denied', function (info) {
  // a document failed to replicate, e.g. due to permissions
}).on('complete', function (info) {
  // handle complete
}).on('error', function (err) {
  // handle error
});

sync.cancel(); // whenever you want to cancel

but I think this should rather be

var sync = PouchDB.sync('mydb', 'http://localhost:5984/mydb', {
  live: true,
  retry: true
});

sync.on('change', function (info) {
  // handle change
}).on('paused', function () {
  // replication paused (e.g. user went offline)
}).on('active', function () {
  // replicate resumed (e.g. user went back online)
}).on('denied', function (info) {
  // a document failed to replicate, e.g. due to permissions
}).on('complete', function (info) {
  // handle complete
}).on('error', function (err) {
  // handle error
});

sync.cancel(); // whenever you want to cancel

??

ronycohen commented 8 years ago

+1

I encounter errors on ANDROID device (ionic)

with PouchDB 5.1.0

image

the remote DB is cloudant and has the CORS enabled.

image

and getting this error :

image

I don't have issue on the chrome browser

nolanlawson commented 8 years ago

Does this only occur with Cloudant? Which browser does it occur in?

Also please please please post screenshots of the Network panel containing the original error, because the "CustomPouchError - 500 - Database encountered an unknown error" gives us zero information.

nolanlawson commented 8 years ago

@simonaberry what is o.company.cancel? Nowhere in the PouchDB codebase do we have a .company.

nolanlawson commented 8 years ago

@simonaberry those two code snippets are equivalent, and we have many many unit tests to verify that, e.g. this one).

simonaberry commented 8 years ago

As I have multiple pouchdbs (one is called 'company') I am using a object to keep this tidy

var sync = {
    company : null,
    people : null
};

//start sync
sync.company = db.company.sync(companyUrl, {live: true, retry: true});  //db.company is a PouchDB

//cancel sync
if (sync.company) sync.company.cancel();
simonaberry commented 8 years ago

Regarding cancel():

I see that the unit test either rejects or resolves an outer promise inside the 'on' handlers.

In normal use, should we be doing any resolving/rejection within an 'on' handler?? If so, how do I access the Promise ?

Because when I inspect the sync object if I use a chain (my code has no resolves/rejections in the on handlers)

screen shot 2015-12-13 at 6 31 21 am

but this when I break the chain

screen shot 2015-12-13 at 6 26 49 am

with

screen shot 2015-12-13 at 6 28 38 am
simonaberry commented 8 years ago

I have only tried with Cloudant. I will do some tests with a local couch and see what happens

I also got this error today, which may or may not help?

offline detected - stopping sync
online detected - starting sync
(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit. 11
  EventEmitter.addListener  
  EventEmitter.once 
  Changes   
  AbstractPouchDB.changes   
  eventFunction 
  EventEmitter.emit 
  Changes.notify    
  api._changes  
  Changes.doChanges 
  Changes   
  AbstractPouchDB.changes   
  getChanges    
  onChangesComplete 

  EventEmitter.addListener  
  EventEmitter.once 
  Changes   
  AbstractPouchDB.changes   
  eventFunction 
  EventEmitter.emit 
  Changes.notify    
  api._changes  
  Changes.doChanges 
  Changes   
  AbstractPouchDB.changes   
  getChanges    
  onChangesComplete 
simonaberry commented 8 years ago

here is the full Network screenshot:

screen shot 2015-12-13 at 9 24 28 am
simonaberry commented 8 years ago

I have tested with a local CouchDB instance, and still get the CORS warning (is CORS even relevant if everything is running on my localhost???) , although not nearly as much....

screen shot 2015-12-13 at 12 38 39 pm
ronycohen commented 8 years ago

Does this only occur with Cloudant? Which browser does it occur in?

Yes on Cloudant, I'm on Android Ionic Framework, then I assume it's Chrome.

Sturgelose commented 8 years ago

@ronyrun, some info here because I'm also using Ionic framework for my app and had also huge problems with CORS.

The CORS problem comes form the Cross-Origin Resource Sharing. The thing is that if you are running your app using the command ionic serve, of course you will see that the app runs in chrome and all the files are changed on the fly. However there is where you have the problem: because there is a local server serving you the files, there is a man in the middle (even if it's in your computer).

Then CORS has problems because it's sharing the code with this man-in-the-middle server and it does changes, when the origin of the call comes from your browser, so total crash by CORS.

So, if you want to check, run the app from an emulator, or directly from an android or ios phone and you should see that there is no problem :) (You can still debug the app in android from chrome using remote debugger in chrome though)

In order to fix that in the browser you can setup a proxy, or setup CORS in the server(as you did). However, I have had a problem that recently, you can't allow a CORS header to be * as it crashes, mostly because authentication and CORS issues (it might be your problem, together with ionic in the middle serving). So, maybe try to use what Ionic provides: http://blog.ionic.io/handling-cors-issues-in-ionic/, check the section "Setting up the proxy server". You can also try some plugins from GoogleChrome or even completely disable CORS using the --disable-web-security flag in Chrome.

Hope this bit of info helps!

ronycohen commented 8 years ago

hi @Sturgelose thx for your answer.

the problem that I encounter occures only on device and not on the local desktop Chrome. I encounter this cors issue only with the 5.1.0 and not with the 5.0.0

mlegenhausen commented 8 years ago

I have the problem on a local system with pouch-server and a local http connection. After exactly 30 seconds of no changes in the database the connection gets closed with an error 500. It seems there is no heartbeat that keeps the connection alive even if I set the heartbeat manually.

It first seems that it is the same cors error. But it is only a warning, that comes when you run on a different port than your webserver. The error occurs just before the error occurs. You can eliminate this problem by proxing your pouchdb instance. I am currently using the webpack-dev-server proxy option. But the connection lost is the main problem.

ParsaAkbari commented 8 years ago

I am observing a similar problem to @ronyrun, I am using Ionic and the app works fine both locally and within the chrome browser on the device, however when building and installing the apk the error occurs. I am using the 'replicate.from' method to sync with a couchdb instance.

Just to clarifyfor @Sturgelose couchdb is set up on a remote server (ec2 instance) while ionic serve is being run locally. So in both cases, (chrome web app, and android application run) the data is passed through a 'middle man' if I understand your post correctly. However things work fine in the chrome web app and not when the application is built on android.

I don't think CORS is relevant, because if it where the app would not function both in the chrome web app and when run from a installed android apk. Using a samsung galaxy sIII android device.

A bit more information

The following code:

    localCollegeDB.replicate.from(remoteCollegeDB, opts
    ).on('complete', function(info) {
                    ..................
    }).on('error', function (err) {
        console.log(err);
    })

output:

 {"status":500,"name":"unknown_error","message":"Database encountered an unknown error"}

Strangely, when checking the couchdb log file there is no evidence of an attempt to connect from the application. This isn't the case when running with the web application.

Complete logcat output for the process http://pastebin.com/16WcYuxU

Perhaps I should submit this as a new bug report, @nolanlawson any suggestions?

ronycohen commented 8 years ago

OK,

@nolanlawson

With 5.1.0 on the device Android Chrome Ionic.

PouchDB: the remote database may not have CORS enabled.If not please enable CORS: http://pouchdb.com/errors.html#no_access_control_allow_origin_header

image

image

image

image

On the DEVICE :

image

the device Log :

image

nolanlawson commented 8 years ago

@ronyrun It looks like your user became logged out? I really can't tell, because I don't see the response from the server. Sorry I can't help more.

ronycohen commented 8 years ago

I opened a ticket on the cloudant side

BenRayner commented 8 years ago

I'm encountering the same problem with Cloudant. PouchDB, Ionic Framework and Cloudant. Application works correctly when serving through the browser and replicates with Cloudant but when it is deployed to an actual device PouchDB fails to replicate with an error 500. CORS is enabled in the Cloudant account.

1 2

BenRayner commented 8 years ago

Not sure if it helps but I managed to get it working using pouchdb-authentication library but I had to mangle it a little. First as per Cloudants docs I had to set Content-Type to application/x-www-form-urlencoded while calling pouchdb-authentication's login function but that would just produce this error from Cloudant:

req

I ended up modifying pouchdb.authentication.js login function to look for the 'application/x-www-form-urlencoded' content type and encode the credentials in the request body as 'name=' + username + '&password=' + password' instead of '{ name : username, password : password };'

Deploying the app still produces some errors result

However, replication with the remote Cloudant DB is successful. Is there a better way to go about this?. Thanks.

ronycohen commented 8 years ago

@nolanlawson we don't get any response from the server. We encounter a Cors issue throw by PouchDB. PouchDB: the remote database may not have CORS enabled.If not please enable CORS

I think we get this error on a _bulk_get query attempt from Pouch to Cloudant. Also, even if I blanked some confidential information.

We can see that the green log and the cloudant link are truncated :

image

shahzainb commented 8 years ago

Hi, we're receiving the same issues as on this ticket. Got a hybrid app (using cordova) running PouchDB with live replication, and we get the same CORS issues. The remote DB is on Cloudant with CORS enabled if that helps.

If you need example code, feel free to ask.

Thanks.

nolanlawson commented 8 years ago

I still don't understand what's going on, because no one has provided a test case, but my hunch is that this is a Cloudant bug related to accessing the non-existent _bulk_get.

kabus202 commented 8 years ago

Yep same issue here, with 5.1.0 also with nightly. I use my own couchdb server. When my op resumes (iOS) i get this message --> {"status":500,"name":"unknown_error","message":"Database encountered an unknown error","error":true}

ronycohen commented 8 years ago

@nolanlawson is there any trick for testing in order to cancel the _bulk_get calls ?

octopitus commented 8 years ago

Got the same issue here. Remote server using pouchdb-server. Although CORS enabled.

nolanlawson commented 8 years ago

Gentle reminder: "me too", "+1", etc. does not get the issue resolved any faster. What does: providing a reproducible test case. E.g. a minimal Cordova project that reproduces the bug.

@ronyrun No, you cannot. We didn't plan for the case where simply doing the request would cause a modal popup to appear.

kabus202 commented 8 years ago

@nolanlawson This is how you maybe can reproduce it:

ionic:

var changes = db.changes({ since: 'now', live: true, include_docs: true }).on('change', function(change) {

    onChange(change);

    // handle change
  }).on('complete', function(info) {
    // changes() was canceled
  }).on('error', function (err) {
    console.log(JSON.stringify(err))
  });

when i close the app ( and screen goes out and when i reopen the app i'm getting this error in console). (iOS 9.2)

Maybe it can help. kab

alexander-entin commented 8 years ago

Below is a full example demonstrating the issue (or maybe another one). Run it in Chrome, wait 30 sec and you'll get 500 and sync will be stopped. Running the same against a remote DB on another domain also gives CORS warning. So, the warning is somewhat confusing and irrelevant.

<script src="//cdn.jsdelivr.net/pouchdb/5.1.0/pouchdb.min.js"></script>
<script>
    PouchDB.debug.enable('*')
    var localDb = new PouchDB('test')
    // PouchDB is running on localhost:
    // npm install -g pouchdb-server
    // pouchdb-server
    var remoteDb = new PouchDB('http://localhost:5984/test')
    localDb.sync(remoteDb, { live: true })
</script>

PS. Adding retry: true forces it to re-establish connection at a cost of 2KB/30sec (250KB/hour).

PPS. Leave it running with retry: true and in few minutes it will give warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

ronycohen commented 8 years ago

@alexander-entin I don't think this is related.

ronycohen commented 8 years ago

I started a ionic project in order to reproduce the issue. I added the crosswalk, and Whitelist Plugin

replicate.to, sync and change are working properly with 5.1.0.

I'll continue the tests.

ParsaAkbari commented 8 years ago

@nolanlawson @ronyrun I have a testcase of the error I am experiencing working here: https://bitbucket.org/pakbari/pouchdb_testcase/src

CORS settings on couchdb are here (need admin access to view): http://pastebin.com/KxNkUwib

Things work fine on: Google Chrome Desktop Browser Google Chrome Android Browser

Status 500 unknown error when running: Firefox Desktop Browser APK Build Android

Would be interesting to try running on iOS.

Really simple testcase, all the code is contained within js/app.js templates/colleges.html index.html

Hope this helps solve the problem, thanks for your time!

EDIT: Now working on device but strangely not on firefox on desktop. Not too bothered as I dont have any intention of running on firefox.

pablomaurer commented 8 years ago

Don't have the time to read everything. But I also had CORS error and throw in what i found out.

Fix for all POST requests are failing, but GET are working: I changed CouchDB settings from WWW-Authenticate = Basic realm="Administrator" to WWW-Authenticate = Other realm="App"and all worked fine again. (side effect -> you will never see again a popup asking for login, so you may cannot access fauxton etc. anymore)

If you use Cordova platform ios below 4.0.0 you cannot use cordova-plugin-whitelist 1.1.0 you have to upgrade the cordova ios platform or downgrade the plugin to v1.0.0 (Maybe on Android there is something similiar?)

Add this new meta tag security policy to your index described in cordova-plugin-whitelist.

I also read that CORS is get active when server1 makes a request to server2. But when you deployed your app there is only 1 server running, so there should not be any cors problem. Then it's most likely something other like authentication.

So I hope this stuff may helps somebody.. If you not give us a sample application with a sample database it's impossible to help. I can look more into this in about 2 weeks, till then good luck with this stupid cors stuff..

simonaberry commented 8 years ago

@nolanlawson simple test case showing the error

https://plnkr.co/edit/b68N4G8KeSZSkSQUCBoP?p=preview

I get the CORS warning in Chrome, FF && IE

ronycohen commented 8 years ago

@simonaberry did you try with the new version 5.2.0 ?

simonaberry commented 8 years ago

I can confirm that the warnings are not present when using 5.2.0 (see same plunker)

Yay!

ronycohen commented 8 years ago

I confirm it too

pablomaurer commented 8 years ago

Me too, Never was happier about a release of PouchDB ;)