Using `instanceof` on objects created with constructors from deep npm dependencies

后端 未结 2 551
傲寒
傲寒 2021-02-19 00:48

Background:

I have an npm module that I have common error handling code in, including a custom error:

function CustomError () { /* ... */ }
CustomError         


        
2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-19 01:28

    What do you mean by:

    After some debugging I've discovered (somewhat obviously in hindsight) that errors created in 'module-a' are not instances of errors created by 'module-b'.

    Error object can't be instance of another error object. Or you are saying that errors from module-a or module-b when doing something like err instanceof CustomError are returning different results? Having in mind that instanceof tests presence of constructor.prototype in object's prototype chain both errors from those modules should return true by code that you posted, when tested againt CustomError.

    Can you show how you are creating those errors in those modules?

    This is because both modules have their own copy of the JS file containing the CustomError constructor, which are both run independently.

    Again, im confused by this statement. What do you mean by both modules have their own copy of something? Lets have small example:

    // custom-error.js
    'use strict'
    
    function CustomError () {}
    
    CustomError.prototype = Object.create(Error.prototype)
    CustomError.prototype.constructor = CustomError
    
    module.exports = CustomError
    
    // module-a.js
    const CustomError = require('./custom-error')
    const err = new CustomError(...)
    module.exports = err
    
    // module-b.js
    const CustomError = require('./custom-error')
    const err = new CustomError(...)
    module.exports = err
    
    // dummy file to require those
    const CustomError = require('./custom-error')
    const errA = require('./module-a')
    const errB = require('./module-b')
    

    First both errA and errB should be an instanceof CustomError:

    console.log(errA instanceof CustomError) // yields true
    console.log(errB instanceof CustomError) // yields true
    

    cunstructor property of errA and errB that will be found in prototype chain, should have reference that points to same function object CustomError

    console.log(errA.constructor === errB.constructor) // yields true
    

    Lets introduce also filtered catch example:

    const Promise = require('bluebird')
    
    Promise.resolve()
    .then(() => {
      throw errA
    })
    .catch(CustomError, err => {
      console.log('instance of CustomError catched', err)
      throw errB
    })
    .catch(CustomError, err => {
      console.log('instance of CustomError catched again', err)
    })
    

    Results:

    instance of CustomError catched [Error]
    instance of CustomError catched again [Error]
    

    And last thing, what do you mean in your example when you say deep npm dependencies? This CustomError thing is your module or 3rd party lib? The fact that is 3rd party module or not, that should not change anything.

提交回复
热议问题