{"action":"created","issue":{"url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/70","repository_url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk","labels_url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/70/labels{/name}","comments_url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/70/comments","events_url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/70/events","html_url":"https://github.com/Bitcoin-com/wormhole-sdk/issues/70","id":370692163,"node_id":"MDU6SXNzdWUzNzA2OTIxNjM=","number":70,"title":"Error Handling Best Practices","user":{"login":"christroutner","id":9870991,"node_id":"MDQ6VXNlcjk4NzA5OTE=","avatar_url":"https://avatars0.githubusercontent.com/u/9870991?v=4","gravatar_id":"","url":"https://api.github.com/users/christroutner","html_url":"https://github.com/christroutner","followers_url":"https://api.github.com/users/christroutner/followers","following_url":"https://api.github.com/users/christroutner/following{/other_user}","gists_url":"https://api.github.com/users/christroutner/gists{/gist_id}","starred_url":"https://api.github.com/users/christroutner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/christroutner/subscriptions","organizations_url":"https://api.github.com/users/christroutner/orgs","repos_url":"https://api.github.com/users/christroutner/repos","events_url":"https://api.github.com/users/christroutner/events{/privacy}","received_events_url":"https://api.github.com/users/christroutner/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-10-16T16:19:10Z","updated_at":"2018-10-22T13:44:47Z","closed_at":"2018-10-22T13:44:47Z","author_association":"COLLABORATOR","body":"This Issue continues the discussion of error handling best practices, and builds\r\non top of [this Issue for the rest.bitcoin.com repo](https://github.com/Bitcoin-com/rest.bitcoin.com/issues/29). This issue focuses on\r\nthe client-side libraries such as [BITBOX](https://github.com/Bitcoin-com/bitbox-javascript-sdk) and [Wormhole](https://github.com/Bitcoin-com/wormhole-sdk).\r\n\r\nAgain, I'll focus on the Wormhole `dataRetrieval/info` endpoint as an example,\r\nand use the common `ECONNRESET` error as an example.\r\n\r\nHere is the current code in [wormhole-sdk/src/DataRetrieval.js](https://github.com/Bitcoin-com/wormhole-sdk/blob/38d91d9fd654ba993e225fc596306326550515fc/src/DataRetrieval.js#L84).\r\n\r\n```javascript\r\nasync info() {\r\n  try {\r\n    const response = await axios.get(`${this.restURL}dataRetrieval/info`)\r\n    return response.data\r\n  } catch (error) {\r\n    throw error.response.data\r\n  }\r\n}\r\n```\r\n\r\nAfter implementing the suggested error handling improvements in rest.bitcoin.com,\r\nthe above code returns this error message:\r\n\r\n```\r\nTypeError: Cannot read property 'data' of undefined\r\n    at DataRetrieval.info (/home/trout/work/bch/wormhole-sdk/lib/DataRetrieval.js:101:30)\r\n    at process._tickCallback (internal/process/next_tick.js:68:7)\r\n```\r\n\r\nWhich is completely unhelpful. And the above message is caused by the `catch`\r\nhandler experiencing an unhandled error because `error.response.data` does not\r\nexist.\r\n\r\nChanging to this:\r\n\r\n```javascript\r\nasync info() {\r\n  try {\r\n    const response = await axios.get(`${this.restURL}dataRetrieval/info`)\r\n    return response.data\r\n  } catch (error) {\r\n    if (error.response && error.response.data) throw error.response.data\r\n    throw error\r\n  }\r\n}\r\n```\r\n\r\nwill results in this error message instead:\r\n\r\n```\r\n{ Error: socket hang up\r\n    at createHangUpError (_http_client.js:322:15)\r\n    at Socket.socketOnEnd (_http_client.js:425:23)\r\n    at Socket.emit (events.js:187:15)\r\n    at endReadableNT (_stream_readable.js:1092:12)\r\n    at process._tickCallback (internal/process/next_tick.js:63:19)\r\n  code: 'ECONNRESET',\r\n  config:\r\n   { adapter: [Function: httpAdapter],\r\n     transformRequest: { '0': [Function: transformRequest] },\r\n     transformResponse: { '0': [Function: transformResponse] },\r\n     timeout: 0,\r\n     xsrfCookieName: 'XSRF-TOKEN',\r\n     xsrfHeaderName: 'X-XSRF-TOKEN',\r\n     maxContentLength: -1,\r\n     validateStatus: [Function: validateStatus],\r\n     headers:\r\n      { Accept: 'application/json, text/plain, */*',\r\n        'User-Agent': 'axios/0.17.1' },\r\n     method: 'get',\r\n     url: 'http://localhost:3000/v1/dataRetrieval/info',\r\n     data: undefined },\r\n  request:\r\n   Writable {\r\n     _writableState:\r\n      WritableState {\r\n        objectMode: false,\r\n        highWaterMark: 16384,\r\n        finalCalled: false,\r\n        needDrain: false,\r\n        ending: false,\r\n        ended: false,\r\n        finished: false,\r\n        destroyed: false,\r\n        decodeStrings: true,\r\n        defaultEncoding: 'utf8',\r\n        length: 0,\r\n        writing: false,\r\n        corked: 0,\r\n        sync: true,\r\n        bufferProcessing: false,\r\n        onwrite: [Function: bound onwrite],\r\n        writecb: null,\r\n        writelen: 0,\r\n        bufferedRequest: null,\r\n        lastBufferedRequest: null,\r\n        pendingcb: 0,\r\n        prefinished: false,\r\n        errorEmitted: false,\r\n        emitClose: true,\r\n        bufferedRequestCount: 0,\r\n        corkedRequestsFree: [Object] },\r\n     writable: true,\r\n     _events:\r\n      { response: [Function: handleResponse],\r\n        error: [Function: handleRequestError] },\r\n     _eventsCount: 2,\r\n     _maxListeners: undefined,\r\n     _options:\r\n      { protocol: 'http:',\r\n        maxRedirects: 21,\r\n        maxBodyLength: 10485760,\r\n        hostname: 'localhost',\r\n        port: '3000',\r\n        path: '/v1/dataRetrieval/info',\r\n        method: 'get',\r\n        headers: [Object],\r\n        agent: undefined,\r\n        auth: undefined,\r\n        nativeProtocols: [Object],\r\n        pathname: '/v1/dataRetrieval/info' },\r\n     _redirectCount: 0,\r\n     _redirects: [],\r\n     _requestBodyLength: 0,\r\n     _requestBodyBuffers: [],\r\n     _onNativeResponse: [Function],\r\n     _currentRequest:\r\n      ClientRequest {\r\n        _events: [Object],\r\n        _eventsCount: 6,\r\n        _maxListeners: undefined,\r\n        output: [],\r\n        outputEncodings: [],\r\n        outputCallbacks: [],\r\n        outputSize: 0,\r\n        writable: true,\r\n        _last: true,\r\n        chunkedEncoding: false,\r\n        shouldKeepAlive: false,\r\n        useChunkedEncodingByDefault: false,\r\n        sendDate: false,\r\n        _removedConnection: false,\r\n        _removedContLen: false,\r\n        _removedTE: false,\r\n        _contentLength: 0,\r\n        _hasBody: true,\r\n        _trailer: '',\r\n        finished: true,\r\n        _headerSent: true,\r\n        socket: [Socket],\r\n        connection: [Socket],\r\n        _header:\r\n         'GET /v1/dataRetrieval/info HTTP/1.1\\r\\nAccept: application/json, text/plain, */*\\r\\nUser-Agent: axios/0.17.1\\r\\nHost: localhost:3000\\r\\nConnection: close\\r\\n\\r\\n',\r\n        _onPendingData: [Function: noopPendingOutput],\r\n        agent: [Agent],\r\n        socketPath: undefined,\r\n        timeout: undefined,\r\n        method: 'GET',\r\n        path: '/v1/dataRetrieval/info',\r\n        _ended: false,\r\n        res: null,\r\n        aborted: undefined,\r\n        timeoutCb: null,\r\n        upgradeOrConnect: false,\r\n        parser: null,\r\n        maxHeadersCount: null,\r\n        _redirectable: [Circular],\r\n        [Symbol(isCorked)]: false,\r\n        [Symbol(outHeadersKey)]: [Object] },\r\n     _currentUrl: 'http://localhost:3000/v1/dataRetrieval/info' },\r\n  response: undefined }\r\n```\r\n\r\nWhile this output is verbose and ugly, it's also full of data that the end users\r\napplication can interrogate to understand *what happened* and *how to handle it*.\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/comments/431839958","html_url":"https://github.com/Bitcoin-com/wormhole-sdk/issues/70#issuecomment-431839958","issue_url":"https://api.github.com/repos/Bitcoin-com/wormhole-sdk/issues/70","id":431839958,"node_id":"MDEyOklzc3VlQ29tbWVudDQzMTgzOTk1OA==","user":{"login":"cgcardona","id":260614,"node_id":"MDQ6VXNlcjI2MDYxNA==","avatar_url":"https://avatars3.githubusercontent.com/u/260614?v=4","gravatar_id":"","url":"https://api.github.com/users/cgcardona","html_url":"https://github.com/cgcardona","followers_url":"https://api.github.com/users/cgcardona/followers","following_url":"https://api.github.com/users/cgcardona/following{/other_user}","gists_url":"https://api.github.com/users/cgcardona/gists{/gist_id}","starred_url":"https://api.github.com/users/cgcardona/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgcardona/subscriptions","organizations_url":"https://api.github.com/users/cgcardona/orgs","repos_url":"https://api.github.com/users/cgcardona/repos","events_url":"https://api.github.com/users/cgcardona/events{/privacy}","received_events_url":"https://api.github.com/users/cgcardona/received_events","type":"User","site_admin":false},"created_at":"2018-10-22T13:44:47Z","updated_at":"2018-10-22T13:44:47Z","author_association":"MEMBER","body":"Wonderful! This is done https://github.com/Bitcoin-com/wormhole-sdk/commit/d0a6ffdaa8f2c2a4764755f3dc1b72b15e758f77\r\n\r\nLive in v1.2.3 https://github.com/Bitcoin-com/wormhole-sdk/releases/tag/1.2.3"}}
{"actor":{"display_login":"cgcardona"}}