bwgjoseph / mongoose-vs-ottoman

feature comparison between mongoose and ottoman
0 stars 1 forks source link

[error] failed to create collection #90

Closed bwgjoseph closed 3 years ago

bwgjoseph commented 3 years ago

Hi,

I was testing out in pure js and encounter this error (most of the time) when I run the application.

Here's the entire script

const { Ottoman, getModel, Schema, SearchConsistency } = require('ottoman');

const ottoman = new Ottoman();

// fill in your credential
ottoman.connect({
  connectionString: 'couchbase://localhost',
  bucketName: 'messageBucket',
  username: 'user',
  password: 'password',
});

const modelOptions = {
  scopeName: 'messageScope3',
  collectionName: 'messageCollection',
};

const schema = new Schema({
  text: { type: String },
});

ottoman.model('message', schema, modelOptions);

ottoman.start();

const messageModel = getModel('message');
messageModel.create({ text: 'test' })
  .then((result) => console.log(result));

// doing this will give the same error
ottoman.start().then(() => {
  const messageModel = getModel('message');
  messageModel.create({ text: 'test' })
    .then((result) => console.log(result));
});

And this is the error thrown

C:\Users\Joseph\Desktop\otto-js>node index.js
(node:9968) UnhandledPromiseRejectionWarning: Error: failed to create collection
    at C:\Users\Joseph\Desktop\otto-js\node_modules\couchbase\lib\collectionmanager.js:109:15
(Use `node --trace-warnings ...` to show where the warning was created)
(node:9968) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:9968) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:9968) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
(node:9968) UnhandledPromiseRejectionWarning: Error: failed to create collection
    at C:\Users\Joseph\Desktop\otto-js\node_modules\couchbase\lib\collectionmanager.js:109:15
(node:9968) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:9968) UnhandledPromiseRejectionWarning: Error: collection not found
    at _getWrappedErr (C:\Users\Joseph\Desktop\otto-js\node_modules\couchbase\lib\errors.js:836:14)
    at Object.wrapLcbErr (C:\Users\Joseph\Desktop\otto-js\node_modules\couchbase\lib\errors.js:1009:20)
    at C:\Users\Joseph\Desktop\otto-js\node_modules\couchbase\lib\collection.js:572:24
(node:9968) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)

And it will be fine after I run the script the 2nd time onwards.

To replicate the issue consistently, just change the scopeName to something else and run again

AV25242 commented 3 years ago

Yeah this is a known issue, apparently looks like the there is no indication from the server level API as to when a scope is created. For now probably would be good to wrap it in a try catch and retry manually.

bwgjoseph commented 3 years ago

Which portion to retry? Wrap ottoman.start() and retry?

AV25242 commented 3 years ago

@bwgjoseph we will wrap up a retry that will be configurable.

bwgjoseph commented 3 years ago

Nice, thanks. I think it's more apt to have that built into the driver

AV25242 commented 3 years ago

Should be made available in the next Beta release

bwgjoseph commented 3 years ago

@AV25242

This seem to work, but giving another error

$ node .
PathExistsError: path exists
    at _getWrappedErr (C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\errors.js:906:14)
    at Object.wrapLcbErr (C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\errors.js:1009:20)
    at C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\queryexecutor.js:126:26 {
  cause: LibcouchbaseError { code: 402 },
  context: QueryErrorContext {
    first_error_code: 12003,
    first_error_message: 'Keyspace not found in CB datastore: default:messageBucket.messageScope5.messageCollection4',
    statement: 'BUILD INDEX ON `messageBucket`.`messageScope5`.`messageCollection4`(`OttomanmessageScope5message`) USING GSI',
    client_context_id: '014f1fff60426c41',
    parameters: '',
    http_response_code: 500,
    http_response_body: ''
  }
}
_Model {
  text: 'test',
  id: '62bceacc-998d-4c9a-8c23-2c9410701a08',
  _type: 'message'
}

So changing to another scope name like mentioned in the first post no longer throws that error (failed to create collection) but still throwing some weird path exists error.

Then I just keep running again and again by changing to different scope/collections and it will throw this error too and hangs

$ node .
(node:18312) UnhandledPromiseRejectionWarning: Error: collection not found
    at _getWrappedErr (C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\errors.js:836:14)
    at Object.wrapLcbErr (C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\errors.js:1009:20)
    at C:\Users\Joseph\Desktop\projects\otto-js\node_modules\couchbase\lib\collection.js:572:24
(Use `node --trace-warnings ...` to show where the warning was created)
(node:18312) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:18312) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

So it's quite random

AV25242 commented 3 years ago

I think this #97 are both related to a common problem that is waiting for Indexes to be build. While I understand this is too much noise and also agree with your prior statement that as an end-user you dont have any control over when the Indexes are build. So let me walk you through why what we think is not trivial.

       Currently creation of Indexes are deferred i.e we call deferred = true you can find a [high level intro here ](https://blog.couchbase.com/deferring-of-index-creation/). What this does is works asynchronously that means your application is not waiting for the Indexes to be made available. Building of Indexes can take from few milliseconds to even minutes depending on the amount of documents / node configuration etc. (lets not get into that details). And the best option was to implicitly create indexes with deferred : true. Now there could be a situation where documents may not exist or may exist only in a small quantity and at that point deferred : false will not have any major impact, but today you cannot set it via Ottoman on purpose.

I hope by now you would have understood why it is what it is. The good news is that setting up of Indexes is a one time thing and there are alternatives like building via console etc as a setup process.

While we are looking into what can be done (either make deferred option available and leave it to the endusers discretion to use it) or may be provide a method that accepts a query and when you call this method with the query the framework keeps trying till the query execution is successful. This is still under consideration/ discussion but will be a low priority at this moment.

Until then try to create the Index first and see if you can overcome this situation. If so then probably close one of the ticket probably this one and keep the other open.

bwgjoseph commented 3 years ago

The good news is that setting up of Indexes is a one time thing and there are alternatives like building via console etc as a setup process.

Agreed. I'm not sure what's the best way to handle this too (at the moment), given that I don't have the complete picture/understanding of how it works internally but since there's already a discussion going on, I think you guys are the best to manage it.

My only feedback here is that to provide a better developer experience around this either by throwing a better error or to provide some options to wait until all indexes are ready before starting the server/service. If the developer wants to let the index build on the background while allowing the server/service to still start first, then any query before the index(es) is build, should just fallback to the primary index? where the query still works but slower because not using index. I'm not sure if this is feasible though, just a thought.

And since the original issue is resolved, and what's left is another issue, I'll close this