Unhandledpromiserejectionwarning: Typeerror: Cannot Read Property 'fetchmember' of Null

Node.js 6.6.0 added a sporadically useful bug/characteristic: logging unhandled hope rejections to the panel by default. In other words, the below script will impress an error to the console:

                      Promise.reject(new            Error('woops'));            /* Output: $ node test.js (node:7741) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: woops (node:7741) DeprecationWarning: Unhandled promise rejections are deprecated. In the hereafter, promise rejections that are not handled volition terminate the Node.js process with a non-nil exit code. */                  

Bluebird has supported similar behavior for quite a while. I've vocally expressed my distaste for this behavior in the past, information technology's actually i of the many reasons why I don't utilize bluebird. But now that this behavior is in core node, information technology appears nosotros're all stuck with it, so we better learn to have advantage of it.

What is an Unhandled Rejection?

"Rejection" is the canonical term for a hope reporting an error. As defined in ES6, a promise is a state machine representation of an asynchronous performance and can be in one of iii states: "pending", "fulfilled", or "rejected". A awaiting hope represents an asynchronous functioning that's in progress and a fulfilled promise represents an asynchronous performance that's completed successfully. A rejected promise represents an asynchronous operation that failed for some reason. For example, trying to connect to a nonexistent MongoDB instance using the MongoDB driver volition give you a promise rejection:

                      const            { MongoClient } =            crave('mongodb');  MongoClient.connect('mongodb://notadomain');            /* Output: $ node exam.js (node:9563) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [notadomain:27017] on first connect [MongoError: getaddrinfo ENOTFOUND notadomain notadomain:27017] (node:9563) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are non handled will finish the Node.js process with a non-nil exit lawmaking. */                  

Remember that the ES6 fashion promise constructor takes an "executor" function that takes 2 functions as arguments, resolve and decline. I way to crusade a promise rejection is to call reject():

                      new            Promise((resolve, turn down) => {   setTimeout(() => pass up('woops'),            500); });            /* Output: $ node test.js (node:8128) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): woops (node:8128) DeprecationWarning: Unhandled hope rejections are deprecated. In the future, promise rejections that are not handled volition end the Node.js procedure with a non-null get out code. */                  

Another fashion is to throw an exception in the executor function:

                      new            Hope(() => {            throw            new            Error('exception!'); });            /* Output $ node test.js (node:8383) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: one): Error: exception! (node:8383) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zilch exit lawmaking. */                  

Some argue that throwing an exception in the executor function is bad practice. I strongly disagree. Consolidated mistake handling is a strong design pattern, and going back to the days where we had to wrap async function calls in try/catch as well as handle the callback fault param is a step in the incorrect direction.

Chaining is how y'all handle hope rejections. ES6 promises have a handy .catch() helper role for treatment rejections.

                      new            Promise((_, reject) => refuse(new            Error('woops'))).            // Prints "caught woops"            grab(error => {            console.log('caught', mistake.message); });            // Equivalent. `.catch(fn)` is essentially identical to `.then(null, fn)`            new            Promise((_, refuse) => reject(new            Mistake('woops'))).            // Prints "defenseless woops"            then(cipher, error => {            console.log('caught', fault.bulletin); });        

Seems like shooting fish in a barrel, right? How about the beneath code, what volition it print?

                      new            Hope((_, decline) => reject(new            Mistake('woops'))).            grab(fault => {            console.log('defenseless', err.message); });        

It'll impress out an unhandled rejection warning. Notice that err is not defined!

          $ node test.js (node:9825) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ReferenceError: err is not defined (node:9825) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, hope rejections that are not handled will end the Node.js process with a non-zero exit code.        

This is why unhandled rejections can exist so insidious. You might think you defenseless an fault, just your error handler might have caused some other fault. You get a similar problem if y'all return a promise in your .take hold of() function. For instance, permit'southward say yous use an misconfigured scout client for logging errors and return a promise representing tracking the fault to sentry.

                      const            picket =            require('raven');            new            Promise((_, decline) => reject(new            Error('woops'))).            catch(error =>            new            Promise((resolve, decline) => {     sentry.captureMessage(error.message,                          part(error)            {            if            (error) {            return            reject(mistake);       }       resolve();     });   }));            /* Output $ node test.js (node:10019) UnhandledPromiseRejectionWarning: Unhandled hope rejection (rejection id: 3): TypeError: Cannot read holding 'user' of undefined (node:10019) DeprecationWarning: Unhandled hope rejections are deprecated. In the futurity, promise rejections that are non handled volition terminate the Node.js process with a non-zero get out lawmaking. */                  

In that location are a lot of nasty gotchas with unhandled rejections. That'southward why Node.js gives you a mechanism for globally handling unhandled rejections.

The unhandledRejection Event

The node process global has an unhandledRejection event for unhandled promise rejection. Bluebird also emits this event, so if you practise global.Promise = require('bluebird') the below code volition still work. Your effect handler will receive the promise rejection fault as its beginning parameter:

          process.on('unhandledRejection', error => {            // Will print "unhandledRejection err is not divers"            panel.log('unhandledRejection', error.message); });            new            Promise((_, turn down) => reject(new            Error('woops'))).            grab(fault => {            // Will not execute            console.log('caught', err.message);   });        

Annotation that, while the fault parameter to the 'unhandledRejection' outcome should be a JavaScript error, it doesn't necessarily have to be. Calling reject() with a non-error is considered bad practice, only if you practise, 'unhandledRejection' volition go the argument yous passed to pass up().

          procedure.on('unhandledRejection', error => {            // Prints "unhandledRejection woops!"            console.log('unhandledRejection', mistake.test); });            new            Hope((_, reject) => reject({ test:            'woops!'            }));        

Annotation that if you lot attach a listener to 'unhandledRejection', the default warning to the panel (the UnhandledPromiseRejectionWarning from previous examples) will not print to the console. That bulletin just gets printed if you don't take a handler for 'unhandledRejection'.

If you lot want to suppress the unhandled hope rejection alert, all you need to practise is call .take hold of() on the promise with an empty function.

          process.on('unhandledRejection', fault => {            // Won't execute            console.log('unhandledRejection', error.test); });            new            Promise((_, reject) => reject({ examination:            'woops!'            })).catch(() => {});        

This is how you suppress unhandled rejection handling when you're absolutely sure you don't desire to handle the error. Why would you desire to suppress unhandled rejection handling? Let's say you used sinon to stub out a role that returns a hope in a mocha earlier() exam hook. The below test succeeds:

                      const            sinon =            require('sinon');            const            obj = {   fn: () => {} };  before(              function()            {   sinon.stub(obj,            'fn').returns(Promise.resolve()); });  information technology('works',                          function()            {            return            obj.fn(); });        

Even so, what if you desire to stub out obj.fn() to render a promise that rejects? The beneath script will log an unhandled rejection warning:

                      const            assert =            require('assert');            const            sinon =            require('sinon');            const            obj = {   fn: () => {} };  before(              function()            {   sinon.stub(obj,            'fn').returns(Promise.reject(new            Error('exam'))); });  it('works',                          function()            {            return            obj.fn().grab(error => {     affirm.equal(error.message,            'test');   }); });        

This is where 'unhandledRejection' starts breaking downwards the abstraction barriers of promises. Now, .catch() is no longer a pure function and has global side effects. For example, one style to avoid the unhandled rejection warning above is to phone call .catch() on the promise but non use the promise that .catch() returns:

          earlier(              function()            {            const            p =            Promise.reject(new            Error('test'));   p.catch(() => {});            // No more warning! `.catch()` mutates `p`'s internal state.            sinon.stub(obj,            'fn').returns(p); });        

Implications for Async/Expect

Async/await has a major advantage over building promise bondage manually: await handles .catch() for you. For instance:

                      async                          function              exam()            {            // No unhandled rejection!            await            Hope.decline(new            Mistake('test')); }  test().catch(() => {});        

Nonetheless, find the .catch() call chained onto test(). Remember that an async function returns a promise! No .grab() there volition give you an unhandled rejection.

                      async                          function              test()            {            // No unhandled rejection!            await            Promise.decline(new            Error('examination')); }  test();            /* Output: $ node examination.js (node:13912) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Mistake: examination (node:13912) DeprecationWarning: Unhandled hope rejections are deprecated. In the future, promise rejections that are not handled will end the Node.js procedure with a not-cipher exit code. */                  

Async/await lets yous construct promises that represent complex operations involving loops, conditionals, etc., but in the end you withal get a promise back. Remember to handle your errors!

In example you were wondering, yous cannot brand async functions return a non-native promise. So there's no mode to brand a promise library that bypasses node'southward unhandled rejection handler and integrates with async/await.

          global.Promise =            require('bluebird');            async                          function              test()            {            // No unhandled rejection!            await            Promise.turn down(new            Error('exam')); }            // Prints "faux"            console.log(test().catch(() => {})            instanceof            crave('bluebird'));        

Confused past promise chains? Async/await is the best fashion to compose promises in Node.js. Await handles promise rejections for you, and then unhandled promise rejections go away. My new ebook, Mastering Async/Await, is designed to give y'all an integrated understanding of async/await fundamentals and how async/look fits in the JavaScript ecosystem in a few hours. Get your re-create!

Looking to become fluent in async/await? My new ebook, Mastering Async/Await, is designed to give you an integrated agreement of async/await fundamentals and how async/await fits in the JavaScript ecosystem in a few hours. Get your re-create!

Found a typo or mistake? Open up upwardly a pull request! This post is bachelor as markdown on Github

carneypriont38.blogspot.com

Source: https://thecodebarbarian.com/unhandled-promise-rejections-in-node.js.html

0 Response to "Unhandledpromiserejectionwarning: Typeerror: Cannot Read Property 'fetchmember' of Null"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel