Skip to content

Commit

Permalink
refactor: raise meaningful exceptions when undefined is passed ORM qu…
Browse files Browse the repository at this point in the history
…ery methods
  • Loading branch information
thetutlage committed Mar 8, 2020
1 parent 0f4a080 commit 6864447
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/Database/QueryBuilder/Chainable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import knex from 'knex'
import { Macroable } from 'macroable'
import { Exception } from '@poppinss/utils'
import { ChainableContract, DBQueryCallback } from '@ioc:Adonis/Lucid/DatabaseQueryBuilder'

import { isObject } from '../../utils'
Expand All @@ -34,6 +35,16 @@ export abstract class Chainable extends Macroable implements ChainableContract {
super()
}

/**
* Raises exception when only one argument is passed to a where
* clause and it is a string. It means the value is undefined
*/
private validateWhereSingleArgument (value: any, method: string) {
if (typeof (value) === 'string') {
throw new Exception(`".${method}" expects value to be defined, but undefined is passed`)
}
}

/**
* Resolves column names
*/
Expand Down Expand Up @@ -203,6 +214,7 @@ export abstract class Chainable extends Macroable implements ChainableContract {
* Only callback is allowed as a standalone param. One must use `whereRaw`
* for raw/sub queries. This is our limitation to have consistent API
*/
this.validateWhereSingleArgument(key, 'where')
this.knexQuery.where(this.resolveKey(key, true, this.transformCallback(key)))
}

Expand All @@ -218,6 +230,7 @@ export abstract class Chainable extends Macroable implements ChainableContract {
} else if (operator !== undefined) {
this.knexQuery.orWhere(this.resolveKey(key), this.transformValue(operator))
} else {
this.validateWhereSingleArgument(key, 'orWhere')
this.knexQuery.orWhere(this.resolveKey(key, true, this.transformCallback(key)))
}

Expand All @@ -240,6 +253,7 @@ export abstract class Chainable extends Macroable implements ChainableContract {
} else if (operator !== undefined) {
this.knexQuery.whereNot(this.resolveKey(key), this.transformValue(operator))
} else {
this.validateWhereSingleArgument(key, 'whereNot')
this.knexQuery.whereNot(this.resolveKey(key, true, this.transformCallback(key)))
}

Expand All @@ -255,6 +269,7 @@ export abstract class Chainable extends Macroable implements ChainableContract {
} else if (operator !== undefined) {
this.knexQuery.orWhereNot(this.resolveKey(key), this.transformValue(operator))
} else {
this.validateWhereSingleArgument(key, 'orWhereNot')
this.knexQuery.orWhereNot(this.resolveKey(key, true, this.transformCallback(key)))
}

Expand Down
11 changes: 11 additions & 0 deletions src/Orm/BaseModel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ export class BaseModel implements ModelContract {
value: any,
options?: ModelAdapterOptions,
) {
if (value === undefined) {
throw new Exception('"find" expects a value. Received undefined')
}

return this.query(options).where(this.primaryKey, value).first()
}

Expand All @@ -432,6 +436,9 @@ export class BaseModel implements ModelContract {
value: any,
options?: ModelAdapterOptions,
) {
if (value === undefined) {
throw new Exception('"findOrFail" expects a value. Received undefined')
}
return this.query(options).where(this.primaryKey, value).firstOrFail()
}

Expand All @@ -443,6 +450,10 @@ export class BaseModel implements ModelContract {
value: any[],
options?: ModelAdapterOptions,
) {
if (value === undefined) {
throw new Exception('"findMany" expects a value. Received undefined')
}

return this
.query(options)
.whereIn(this.primaryKey, value)
Expand Down

0 comments on commit 6864447

Please sign in to comment.