Blog / Javascript

Mongoose: corrigindo "Cannot overwrite 'Model' model once compiled"

TTulio Faria 03 de out. de 2016 2 min de leitura
Mongoose: corrigindo "Cannot overwrite 'Model' model once compiled"

Durante o desenvolvimento de um protótipo aqui na empresa, eu me deparei com uma situação bem interessante no Mongoose. Por algum motivo, comecei a receber o seguinte erro: _OverwriteModelError: Cannot overwrite `User` model once compiled. _

C:\\Arquivos\\devpleno\\conteudos\\mongoose-problem-windows\\node\_modules\\mongoose\\lib\\index.js:361
      throw new mongoose.Error.OverwriteModelError(name);
      ^
 OverwriteModelError: Cannot overwrite \`User\` model once compiled.
    at Mongoose.model (C:\\Arquivos\\devpleno\\conteudos\\mongoose-problem-windows\\node\_modules\\mongoose\\lib\\index.js:361:13)
    at Object.<anonymous> (C:\\Arquivos\\devpleno\\conteudos\\mongoose-problem-windows\\User.js:8:27)
    at Module.\_compile (module.js:413:34)
    at Object.Module.\_extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module.\_load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (C:\\Arquivos\\devpleno\\conteudos\\mongoose-problem-windows\\postsController.js:1:74)
    at Module.\_compile (module.js:413:34)
    at Object.Module.\_extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module.\_load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (C:\\Arquivos\\devpleno\\conteudos\\mongoose-problem-windows\\index.js:6:1)

O que me intrigou muito foi que sempre utilizei o Mongoose praticamente da mesma forma. O exemplo que gerou este erro é este aqui:

var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/mongoose-problem')

require('./usersController.js')
require('./postsController.js')

O model User:

var mongoose = require('mongoose')

var userSchema = mongoose.Schema({
  email: String,
  password: String
})

module.exports = mongoose.model('User', userSchema)

E os 2 controllers, que simulam a utilização deste model:

var User = require('./user')
// restante do código do controller

var Post = require('./User')
// restante do código do controller

Bom, analisando o erro novamente, podemos notar que por algum motivo ao executar o código, o módulo onde está o model está sendo instanciado mais de uma vez. E isso acarreta em setar o schema duas vezes, gerando assim este erro.

Se analisarmos como está sendo dado o require em cada controller, vamos notar que um deles está como user e no outro User. No Windows, se tentarmos abrir um arquivo User.js ou user.js, ambos irão apontar para o mesmo local (que foi o que aconteceu aqui).

Porém, o nodejs gerencia os módulos em si de maneira case-sensitive. Então se fizermos: require(’./User’) e require(’./user’), o nodejs vai tentar registrar 2x. O que duplica o registro do schema User no mongoose.

No Linux/Mac isso não aconteceria, pois bem antes de esse erro “pipocar”, o node já iria gritar dizendo que o módulo User.js não existe. E ficaria bem mais simples de encontrar o erro.

Outros efeitos colaterais deste problema:

Se por algum motivo, tivéssemos um trecho de código que não possuísse a restrição do mongoose+schema (de não poder ser registrado mais de uma vez). Este código seria executado 2x no Windows (pois o node registraria 2x o módulo).

Isso poderia gerar um bug/efeito colateral que aconteceria somente no Windows. E o código quebraria quando fosse colocado em produção no Linux. O ideal então é manter um padrão, e chamar no require da mesma forma que o arquivo foi salvo. Evitando assim, muita dor de cabeça.

Curta o DevPleno no Facebook, se inscreva no canal no YouTube e cadastre seu e-mail para não perder as atualizações. Abraço!

T
Escrito por
Tulio Faria

Mestre em Sistemas de Informação pela USP e criador do DevPleno. Iniciou sua carreira como professor com apenas 18 anos em um curso técnico, foram 11 anos em sala de aula formando desenvolvedores fullstack no sul de Minas Gerais.

JavascriptNodeJS
Compartilhar X LinkedIn
Continue lendo

Insights relacionados