Skip to content

Commit

Permalink
Merge pull request #414 from anvilco/newhouse/376/error-handling
Browse files Browse the repository at this point in the history
Error handling
  • Loading branch information
newhouse authored Dec 8, 2023
2 parents 17820e7 + a59fd73 commit f6e0943
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 26 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v3.2.0]
- Swap out `node-fetch` for `@anvilco/node-fetch` in order to fix `Premature close`. https://github.com/anvilco/node-fetch/pull/1
- Fixed bug around some error handling. https://github.com/anvilco/node-anvil/issues/376
- Updated various dependencies

## [v3.1.0]
- Update `node-fetch` to latest and drop `form-data`. https://github.com/anvilco/node-anvil/issues/239
- Update various dependencies
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@anvilco/anvil",
"version": "3.1.0",
"version": "3.2.0-beta.1",
"description": "Anvil API Client",
"author": "Anvil Foundry Inc.",
"homepage": "https://github.com/anvilco/node-anvil#readme",
Expand Down Expand Up @@ -41,6 +41,7 @@
"build": "babel src --out-dir ./dist",
"clean": "yarn rimraf ./dist",
"prepare": "yarn tsc && yarn clean && yarn build",
"publish:beta": "npm publish --tag beta",
"test": "yarn prepare && mocha --config ./test/mocha.js",
"lint": "eslint src/**/*.js test/**/*.js",
"lint:quiet": "yarn run lint --quiet",
Expand All @@ -50,10 +51,10 @@
"test-e2e:install": "npm --prefix test/e2e run prep && npm --prefix test/e2e install"
},
"dependencies": {
"@anvilco/node-fetch": "^3.3.3-beta.0",
"abort-controller": "^3.0.0",
"extract-files": "^13",
"limiter": "^2.1.0",
"node-fetch": "^3.3.2"
"limiter": "^2.1.0"
},
"devDependencies": {
"@babel/cli": "^7.22.10",
Expand Down
18 changes: 16 additions & 2 deletions src/errors.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// See if the JSON looks like it's got errors
export function looksLikeError ({ json }) {
export function looksLikeJsonError ({ json }) {
return !!(json && (json.errors || json.message || json.name))
}

// Should return an array
export function normalizeErrors ({ json, statusText = 'Unknown Error' }) {
export function normalizeJsonErrors ({ json, statusText = 'Unknown Error' }) {
if (json) {
// Normal, GraphQL way
if (json.errors) {
Expand All @@ -31,3 +31,17 @@ export function normalizeErrors ({ json, statusText = 'Unknown Error' }) {
// Hmm, ok. Default way
return [{ name: statusText, message: statusText }]
}

// Should return an array
export function normalizeNodeError ({ error, statusText = 'Unknown Error' }) {
if (error) {
return [pickError(error)]
}

// Hmm, ok. Default way
return [{ name: statusText, message: statusText }]
}

function pickError (error) {
return (({ name, message, code, cause, stack }) => ({ name, message, code, cause, stack }))(error)
}
15 changes: 8 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RateLimiter } from 'limiter'

import UploadWithOptions from './UploadWithOptions'
import { version, description } from '../package.json'
import { looksLikeError, normalizeErrors } from './errors'
import { looksLikeJsonError, normalizeNodeError, normalizeJsonErrors } from './errors'
import { queries, mutations } from './graphql'
import {
isFile,
Expand Down Expand Up @@ -464,7 +464,7 @@ class Anvil {
if (filesMap.size) {
// @ts-ignore
const abortController = new AbortController()
Fetch ??= await import('node-fetch')
Fetch ??= await import('@anvilco/node-fetch')
// This is a dependency of 'node-fetch'`
FormDataModule ??= await import('formdata-polyfill/esm.min.js')
const form = new FormDataModule.FormData()
Expand Down Expand Up @@ -605,7 +605,7 @@ class Anvil {

async _request (...args) {
// Only load Fetch once per module process lifetime
Fetch = Fetch || await import('node-fetch')
Fetch = Fetch || await import('@anvilco/node-fetch')
fetch = Fetch.default
// Monkey-patch so we only try any of this once per Anvil Client instance
this._request = this.__request
Expand Down Expand Up @@ -661,6 +661,7 @@ class Anvil {

let json
let isError = false
let nodeError

const contentType = response.headers.get('content-type') || response.headers.get('Content-Type') || ''

Expand All @@ -671,18 +672,18 @@ class Anvil {
dataType = DATA_TYPE_JSON
try {
json = await response.json()
isError = looksLikeError({ json })
isError = looksLikeJsonError({ json })
} catch (err) {
nodeError = err
if (debug) {
console.warn(`Problem parsing JSON response for status ${statusCode}:`)
console.warn(err)
console.warn('Using statusText instead')
}
}
}

if (isError || statusCode >= 300) {
const errors = await normalizeErrors({ json, statusText })
if (nodeError || isError || statusCode >= 300) {
const errors = nodeError ? normalizeNodeError({ error: nodeError }) : normalizeJsonErrors({ json, statusText })
return { response, statusCode, errors }
}

Expand Down
8 changes: 7 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,13 @@ describe('Anvil API Client', function () {

const result = await client.requestREST('/non-existing-endpoint', options, clientOptions)
expect(result.statusCode).to.eql(404)
expect(result.errors).to.eql([{ message: 'Not Found', name: 'Not Found' }])
expect(result.errors).to.be.an('array').of.length(1)
expect(result.errors[0]).to.include({
name: 'SyntaxError',
message: 'Unexpected token w in JSON at position 0',
code: undefined,
cause: undefined,
})
})

it('sets the rate limiter from the response headers', async function () {
Expand Down
17 changes: 15 additions & 2 deletions types/src/errors.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
export function looksLikeError({ json }: {
export function looksLikeJsonError({ json }: {
json: any;
}): boolean;
export function normalizeErrors({ json, statusText }: {
export function normalizeJsonErrors({ json, statusText }: {
json: any;
statusText?: string;
}): any;
export function normalizeNodeError({ error, statusText }: {
error: any;
statusText?: string;
}): {
name: any;
message: any;
code: any;
cause: any;
stack: any;
}[] | {
name: string;
message: string;
}[];
//# sourceMappingURL=errors.d.ts.map
2 changes: 1 addition & 1 deletion types/src/errors.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion types/src/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"

"@anvilco/node-fetch@^3.3.3-beta.0":
version "3.3.3-beta.0"
resolved "https://registry.yarnpkg.com/@anvilco/node-fetch/-/node-fetch-3.3.3-beta.0.tgz#4d0fdb4214a6c851651333307ee0b32b3068465d"
integrity sha512-hiruVZHjUvBxaTBSCRoeGNRknJWSwatrAm+uczyjcDGMpblOQb28sPjFVqGJ3EyOFzbIfXrm03/uIg8pr1NILA==
dependencies:
data-uri-to-buffer "^4.0.0"
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"

"@babel/cli@^7.22.10":
version "7.23.4"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.23.4.tgz#f5cc90487278065fa0c3b1267cf0c1d44ddf85a7"
Expand Down Expand Up @@ -2971,15 +2980,6 @@ node-domexception@^1.0.0:
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==

node-fetch@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b"
integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
dependencies:
data-uri-to-buffer "^4.0.0"
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"

node-releases@^2.0.13:
version "2.0.13"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d"
Expand Down

0 comments on commit f6e0943

Please sign in to comment.