loopbackio / loopbackio/loopback-datasource-juggler

Model errors when using relations with the MongoDB connector cause crashes

Open
#111 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug help wanted major needs-reproduction
Dominant language
JavaScript
Stars
282
Forks
366
Avg merge
17h 4m
Merged PRs (30d)
10

Description

I have relations setup with a model which includes a property similar to this:

versions: [
  {
    id:         String
  }
]

If the versions property is actually an object, rather than an array (due to an error in saving), loopback crashes when it attempts to resolve relations involving this model.

This is the error I get:

/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/base.js:245
        throw message;
              ^
Error: Items must be an array: [object Object]
  at new List (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/list.js:25:11)
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/model.js:178:39
  at Array.forEach (native)
  at Function.ModelClass.forEachProperty (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/model-builder.js:271:51)
  at ModelConstructor.ModelBaseClass._initProperties (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/model.js:164:8)
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/dao.js:557:13
  at Array.forEach (native)
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/dao.js:554:12
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/include.js:59:11
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:113:21
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:24:16
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/include.js:124:9
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:111:13
  at Array.forEach (native)
  at _each (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:32:24)
  at Object.async.each (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:110:9)
  at processIncludeItem (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/include.js:106:11)
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/include.js:57:5
  at /Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:111:13
  at Array.forEach (native)
  at _each (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:32:24)
  at Object.async.each (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:110:9)
  at Function.Inclusion.include (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/include.js:56:9)
  at Function.f (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/jutil.js:100:15)
  at Function.f [as include] (/Users/zackbloom/s/API/node_modules/loopback-datasource-juggler/lib/jutil.js:100:15)
  at /Users/zackbloom/s/API/node_modules/loopback-connector-mongodb/lib/mongodb.js:519:33
  at /Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/cursor.js:163:16
  at commandHandler (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/cursor.js:709:16)
  at /Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/db.js:1846:9
  at Server.Base._callHandler (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
  at /Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/server.js:468:18
  at [object Object].MongoReply.parseBody (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
  at [object Object].<anonymous> (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/server.js:426:20)
  at [object Object].EventEmitter.emit (events.js:95:17)
  at [object Object].<anonymous> (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
  at [object Object].EventEmitter.emit (events.js:98:17)
  at Socket.<anonymous> (/Users/zackbloom/s/API/node_modules/mongodb/lib/mongodb/connection/connection.js:339:18)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:528:21)

The error itself isn't terrible, but I'd certainly rather it be returned through the HTTP request, rather than crashing the entire app.

I've tried wrapping parts of that stack in a try block, but it looks like the mongodb connector does some fancy magic with nextTick to bypass the actual stack.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the relation-inclusion path in lib/include.js and the property initialization in lib/model.js, then inspect the connector callback in lib/mongodb.js. Reproduce a relation lookup where versions is an object instead of an array; done means the failure is returned through the HTTP request rather than crashing the application.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, mongodb
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.