NODE.JS APPLICATIONS The Mystery of the Missing Stack Trace THE - - PowerPoint PPT Presentation

node js applications
SMART_READER_LITE
LIVE PREVIEW

NODE.JS APPLICATIONS The Mystery of the Missing Stack Trace THE - - PowerPoint PPT Presentation

BUILDING SCALABLE AND DEPENDABLE JAMUND FERGUSON NODE.JS APPLICATIONS The Mystery of the Missing Stack Trace THE MYSTERY OF THE MISSING STACK TRACE Error: Can't set headers after they are sent. at


slide-1
SLIDE 1

NODE.JS APPLICATIONS

BUILDING SCALABLE AND DEPENDABLE

JAMUND FERGUSON
slide-2
SLIDE 2

The Mystery of the Missing Stack Trace

🕶

slide-3
SLIDE 3 THE MYSTERY OF THE MISSING STACK TRACE Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11) at ServerResponse.header (/web/mynodeapp/node_modules/express/lib/response.js:767:10) at ServerResponse.send (/web/mynodeapp/node_modules/express/lib/response.js:170:12) at ServerResponse.res.send (/web/mynodeapp/node_modules/pplogger/index.js:225:18) at done (/web/mynodeapp/node_modules/express/lib/response.js:1004:10) at Stub.callback (/web/mynodeapp/node_modules/adaro/lib/engine.js:137:22) at Stub.flush (/web/mynodeapp/pp/node_modules/dustjs-linkedin/lib/dust.js:513:10) at Chunk.end (/web/mynodeapp/node_modules/dustjs-linkedin/lib/dust.js:612:15) at /web/mynodeapp/node_modules/adaro/lib/patch/index.js:89:53 at /web/mynodeapp/node_modules/adaro/lib/reader/js.js:39:13 at /web/mynodeapp/node_modules/engine-munger/lib/munger.js:85:13 at /web/mynodeapp/node_modules/engine-munger/lib/cache.js:65:13 at /web/mynodeapp/node_modules/graceful-fs/graceful-fs.js:78:16 at /web/mynodeapp/node_modules/async-listener/glue.js:188:31 at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)
slide-4
SLIDE 4

😣

slide-5
SLIDE 5

We had no idea why or where our apps were failing

slide-6
SLIDE 6

WHAT CAN WE DO?

▸ Compare a diff between last known working code ▸ Look through other logs for more information (nginx logs, access logs, etc) ▸ Look at system metrics (is there a memory leak or CPU spike?) ▸ Add console.log statements somewhere??? ▸ Advanced debugging techniques (post-mortem debugging, heapdumps, etc.)

THE MYSTERY OF THE MISSING STACK TRACE
slide-7
SLIDE 7
slide-8
SLIDE 8
slide-9
SLIDE 9 DECRYPT RETURNS A PROMISE ADDUSER EXPECTS A STRING LOG EXPECTS A SMALL OBJECT OR A STRING
slide-10
SLIDE 10

💤

slide-11
SLIDE 11 THE MYSTERY OF THE MISSING STACK TRACE

LESSONS LEARNED

▸ We need better static analysis ▸ We need better debugging tools ▸ We need a consistent way to handle errors ▸ We need to better understand our logging & monitoring💤

slide-12
SLIDE 12

FLOWTYPE & ESLINT

STATIC ANALYSIS WITH

slide-13
SLIDE 13

TYPE CHECKING COULD HAVE CAUGHT THAT BUG WITH 2-LINES OF CODE

STATIC ANALYSIS
slide-14
SLIDE 14 STATIC ANALYSIS

PREVENTING BUGS WITH TYPES

slide-15
SLIDE 15 STATIC ANALYSIS

PREVENTING BUGS WITH TYPES

slide-16
SLIDE 16 STATIC ANALYSIS

FLOW WON’T LET THAT SLIDE

slide-17
SLIDE 17 STATIC ANALYSIS

WHY ADD TYPES TO YOUR JS?

▸ Prevents large % of bugs ▸ Helps surface architectural problems ▸ Both Flow and TypeScript are well maintained, high quality tools ▸ Both syntaxes are light-weight and easy to use ▸ Both allow for gradual adoption

slide-18
SLIDE 18
slide-19
SLIDE 19

🙌 🍪 🚬

slide-20
SLIDE 20

Type systems have a lot in common with linters

slide-21
SLIDE 21 Each JS File Parser (Acorn) Abstract Syntax Tree (AST) Rules Warning Success Errors Architecture of JavaScript Linter (ESLint)
slide-22
SLIDE 22

Linters can only think about one file at a time

slide-23
SLIDE 23 All Your JS Files Flow Types & Relationships Graph Architecture of JavaScript Type System (Flow) Single JS File Warning Success Errors Flow Graph
slide-24
SLIDE 24

COULD A LINTER HAVE HELPED US WITH OUR MYSTERY BUG?

slide-25
SLIDE 25 STATIC ANALYSIS
slide-26
SLIDE 26 STATIC ANALYSIS
slide-27
SLIDE 27 STATIC ANALYSIS

STATIC ANALYZERS AND FORMATTERS ARE PRETTY COOL

FlowType ESLint Prettier
slide-28
SLIDE 28

Unfortunately, we still get bugs from time to time

slide-29
SLIDE 29

INSPECTOR MODULE

DEBUGGING USING THE

slide-30
SLIDE 30 THE BUILT-IN INSPECTOR MODULE
slide-31
SLIDE 31
slide-32
SLIDE 32 THE BUILT-IN INSPECTOR MODULE

SETTING UP A DEBUG MODE

TURN IT ON TURN IT OFF

slide-33
SLIDE 33 THE BUILT-IN INSPECTOR MODULE
slide-34
SLIDE 34 THE BUILT-IN INSPECTOR MODULE Set Breakpoint
slide-35
SLIDE 35 THE BUILT-IN INSPECTOR MODULE PAUSE ON UNCAUGHT EXCEPTIONS
slide-36
SLIDE 36 THE BUILT-IN INSPECTOR MODULE PAUSE ON CAUGHT EXCEPTIONS
slide-37
SLIDE 37 THE BUILT-IN INSPECTOR MODULE
slide-38
SLIDE 38 THE BUILT-IN INSPECTOR MODULE
slide-39
SLIDE 39 THE BUILT-IN INSPECTOR MODULE
slide-40
SLIDE 40 THE BUILT-IN INSPECTOR MODULE
slide-41
SLIDE 41

Don’t try this in production


 STOP

slide-42
SLIDE 42 THE BUILT-IN INSPECTOR MODULE
slide-43
SLIDE 43 THE BUILT-IN INSPECTOR MODULE
slide-44
SLIDE 44 THE BUILT-IN INSPECTOR MODULE https://chromedevtools.github.io/devtools-protocol/
slide-45
SLIDE 45 THE BUILT-IN INSPECTOR MODULE Default Node Error Inspector Based Error
slide-46
SLIDE 46 DEBUGGING NODE.JS APPS

FIND A DEBUGGING APPROACH THAT WORKS FOR YOU AND YOUR TEAM

slide-47
SLIDE 47

ASYNC/AWAIT

ERROR HANDLING USING

slide-48
SLIDE 48 ERROR HANDLING WITH ASYNC/AWAIT
slide-49
SLIDE 49

Errors thrown inside async functions get converted into rejected Promises

💢

slide-50
SLIDE 50 ERROR HANDLING WITH ASYNC/AWAIT
slide-51
SLIDE 51

Async Middleware Pattern

slide-52
SLIDE 52 ERROR HANDLING WITH ASYNC/AWAIT T H I S I S P R E T T Y N I C E
slide-53
SLIDE 53 ERROR HANDLING WITH ASYNC/AWAIT B U T W E D O N ’ T A C T U A L LY C AT C H I T 💤 E R R O R S W I L L B U B B L E U P
slide-54
SLIDE 54 ERROR HANDLING WITH ASYNC/AWAIT

💦

slide-55
SLIDE 55 ERROR HANDLING WITH ASYNC/AWAIT PASS IN YOUR ASYNC MIDDLEWARE RETURN A STANDARD MIDDLEWARE FUNCTION CATCH ANY ERRORS PASS THOSE TO THE EXPRESS ERROR HANDLER EXECUTE THE ASYNC MIDDLEWARE APPLY AS NEEDED
slide-56
SLIDE 56 ERROR HANDLING WITH ASYNC/AWAIT

💦

slide-57
SLIDE 57

Make it easy for your engineers
 to do the right thing

slide-58
SLIDE 58 ERROR HANDLING WITH ASYNC/AWAIT
slide-59
SLIDE 59

Custom Error Classes

slide-60
SLIDE 60 CUSTOM ERRORS
slide-61
SLIDE 61 CUSTOM ERRORS
slide-62
SLIDE 62 CUSTOM ERRORS 1. 2. 3.
slide-63
SLIDE 63 CUSTOM ERRORS
slide-64
SLIDE 64 CUSTOM ERRORS
slide-65
SLIDE 65 CUSTOM ERRORS
slide-66
SLIDE 66 CUSTOM ERRORS

SUMMARY

▸ Don’t use object literals or strings for errors (missing stack trace) ▸ Use the Error built-in object ▸ Subclass Error to add statusCodes or to convert error codes into user-

friendly error messages for localization, etc

▸ We basically have one error class per micro-service to handle parsing the

errors out of the response….

slide-67
SLIDE 67

The Mystery of the Client-Side Errors

slide-68
SLIDE 68 THE MYSTERY OF THE CLIENT-SIDE ERRORS

CLIENT-SIDE MONITORING

BUTTON DOESN’T WORK REAL ISSUE USUALLY IN DEV TOOLS
slide-69
SLIDE 69 THE MYSTERY OF THE CLIENT-SIDE ERRORS

CLIENT-SIDE MONITORING

window.onerror = function (msg, url, line, col, error) {
 // 1. clean up the data
 // 2. log to server w/AJAX or sendBeacon() API
 }
slide-70
SLIDE 70 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE NOTICED A SPIKE DURING DEPLOY

slide-71
SLIDE 71 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE CONGRATULATED OURSELVES…THEN ACTUALLY LOOKED INTO THE BUG

🏇 😯

slide-72
SLIDE 72 THE MYSTERY OF THE CLIENT-SIDE ERRORS
slide-73
SLIDE 73 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE HAVE A LOT OF SERVERS

slide-74
SLIDE 74 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE HAVE A LOT OF SERVERS

slide-75
SLIDE 75 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE HAVE A LOT OF SERVERS

slide-76
SLIDE 76 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE HAVE A LOT OF SERVERS

slide-77
SLIDE 77 THE MYSTERY OF THE CLIENT-SIDE ERRORS

WE HAVE A LOT OF SERVERS

slide-78
SLIDE 78 THE MYSTERY OF THE CLIENT-SIDE ERRORS UI Code Server code A B
slide-79
SLIDE 79 THE MYSTERY OF THE CLIENT-SIDE ERRORS

ROLLING BACK MADE THINGS WORSE

slide-80
SLIDE 80 THE MYSTERY OF THE CLIENT-SIDE ERRORS

LESSONS LEARNED

▸ UI is a huge monitoring blind-spot ▸ Be aware of how the deploy process affects users ▸ Try to make your code changes backwards compatible ▸ Consider separating UI and server deploys

slide-81
SLIDE 81 BUILDING SCALABLE AND DEPENDABLE NODE.JS APPLICATIONS

▸Use static analysis (including types) to catch bugs early ▸Have a plan for debugging apps in production ▸Adopt a consistent approach to error handling ▸Know how to access all of your logs ▸Don’t forget to monitor client-side errors

slide-82
SLIDE 82

THE END