Skip to content

Commit

Permalink
Use verbose flag to show diagnostic errors with model name and record…
Browse files Browse the repository at this point in the history
… data
  • Loading branch information
Pranav Babu committed Dec 3, 2024
1 parent 27f533d commit 4244056
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
20 changes: 16 additions & 4 deletions src/Model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,13 @@ export default class Model {
* @see {Database#batch}
*/
prepareUpdate(recordUpdater: (this) => void = noop): this {
this.__debugInvariant(
!this._preparedState,
`Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`,
)
invariant(
!this._preparedState,
`Cannot update a record with pending changes for model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)} (${this.__debugName})`,
`Cannot update a record with pending changes (${this.__debugName})`,
)
this.__ensureNotDisposable(`Model.prepareUpdate()`)
this._isEditing = true
Expand Down Expand Up @@ -182,9 +186,10 @@ export default class Model {
* @see {Database#batch}
*/
prepareMarkAsDeleted(): this {
this.__debugInvariant(!this._preparedState, `Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`)
invariant(
!this._preparedState,
`Cannot mark a record with pending changes as deleted for model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)} (${this.__debugName})`,
`Cannot mark a record with pending changes as deleted (${this.__debugName})`,
)
this.__ensureNotDisposable(`Model.prepareMarkAsDeleted()`)
this._raw._status = 'deleted'
Expand Down Expand Up @@ -217,9 +222,10 @@ export default class Model {
* @see {Database#batch}
*/
prepareDestroyPermanently(): this {
this.__debugInvariant(!this._preparedState, `Model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)}`)
invariant(
!this._preparedState,
`Cannot destroy permanently record with pending changes for model ${this.constructor.name}, Raw Data: ${JSON.stringify(this._raw)} (${this.__debugName})`,
`Cannot destroy permanently record with pending changes (${this.__debugName})`,
)
this.__ensureNotDisposable(`Model.prepareDestroyPermanently()`)
this._raw._status = 'deleted'
Expand Down Expand Up @@ -464,7 +470,7 @@ export default class Model {
)
invariant(
!(this._getChanges(): $FlowFixMe<BehaviorSubject<any>>).isStopped &&
this._raw._status !== 'deleted',
this._raw._status !== 'deleted',
`Not allowed to change deleted record ${this.__debugName}`,
)
}
Expand All @@ -485,4 +491,10 @@ export default class Model {
logger.debug(`${debugName}: ${this.__debugName}`)
}
}

__debugInvariant(condition: boolean, errorMessage: string): void {
if (this.db.experimentalIsVerbose && !condition) {
logger.debug(errorMessage)
}
}
}
14 changes: 11 additions & 3 deletions src/Model/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { field, date, readonly } from '../decorators'
import { noop } from '../utils/fp'
import sortBy from '../utils/fp/sortBy'
import { sanitizedRaw } from '../RawRecord'
import { logger } from '../utils/common'

import Model from './index'
import { fetchDescendants } from './helpers'
Expand Down Expand Up @@ -419,17 +420,24 @@ describe('Safety features', () => {
})
it('disallows operations on uncommited records', async () => {
const db = makeDatabase()
const spy = jest.spyOn(logger, 'debug')
db.experimentalIsVerbose = true

db.adapter.batch = jest.fn()
await db.write(async () => {
const model = MockModel._prepareCreate(db.get('mock'), () => {})
expect(model._preparedState).toBe('create')

await expectToRejectWithMessage(
model.update(() => {}),
`with pending changes for model MockModel, Raw Data: {"id":"${model._raw.id}"`,
'with pending changes',
)
await expectToRejectWithMessage(model.markAsDeleted(), `with pending changes as deleted for model MockModel, Raw Data: {"id":"${model._raw.id}"`)
await expectToRejectWithMessage(model.destroyPermanently(), `with pending changes for model MockModel, Raw Data: {"id":"${model._raw.id}"`)
expect(spy).toHaveBeenCalledWith(expect.stringMatching('Model MockModel, Raw Data: {'))

await expectToRejectWithMessage(model.markAsDeleted(), 'with pending changes')

await expectToRejectWithMessage(model.destroyPermanently(), 'with pending changes')

expect(() => model.observe()).toThrow('uncommitted')
await db.batch(model)
})
Expand Down

0 comments on commit 4244056

Please sign in to comment.