Skip to content

Commit

Permalink
feat: new error handling (Open-Attestation#110)
Browse files Browse the repository at this point in the history
* feat: new error handling (429, 500 etc)

* feat: add new error types

* chore: rm dist from gitignore

* chore: add dist to gitignore

* chore: add oa-verify dist as workaround

- this will trigger GitGuardian

* chore: cleanup and refactor

* feat: handle missing response (429)

* feat: refactor errors, using EthersError to check instead

- using INVALID_ARGUMENT and SERVER_ERROR

* chore: refactor error + error msg

* fix: lint

* feat: added Mock Svc Worker, test case coverage

- installed msw (mock service worker) to mock http responses
- added test case coverage for ethers SERVER_ERROR

* fix: removed focused test .only

* feat: test case coverage for HTTP response errors

* feat: invalid argument/merkleRoot test coverage

* fix: update test snapshot

* chore: remove dist

* fix: tests, moved msw to devDep

* fix: eslint no-extraneous-dependencies

* chore: dist

* chore: remove dist
  • Loading branch information
gjj authored Aug 31, 2020
1 parent c39b1ca commit 5d301f6
Show file tree
Hide file tree
Showing 10 changed files with 924 additions and 8 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-unused-expressions": "off",
"no-else-return": "off"
"no-else-return": "off",
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.ts", "**/*.test.tsx"]}]
}
}
187 changes: 184 additions & 3 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"eslint-plugin-prettier": "^3.1.4",
"git-cz": "^4.7.0",
"jest": "^26.1.0",
"msw": "^0.20.5",
"prettier": "^2.0.5",
"semantic-release": "^17.1.1",
"ts-jest": "^26.1.1",
Expand Down
4 changes: 4 additions & 0 deletions src/types/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export enum OpenAttestationEthereumDocumentStoreStatusCode {
ETHERS_UNHANDLED_ERROR = 3,
SKIPPED = 4,
DOCUMENT_REVOKED = 5,
INVALID_ARGUMENT = 6,
CONTRACT_NOT_FOUND = 404,
SERVER_ERROR = 500,
}
export enum OpenAttestationDocumentSignedCode {
UNEXPECTED_ERROR = 0,
Expand All @@ -21,7 +23,9 @@ export enum OpenAttestationEthereumTokenRegistryStatusCode {
CONTRACT_ADDRESS_INVALID = 2,
ETHERS_UNHANDLED_ERROR = 3,
SKIPPED = 4,
INVALID_ARGUMENT = 6,
CONTRACT_NOT_FOUND = 404,
SERVER_ERROR = 500,
}
export enum OpenAttestationDnsTxtCode {
UNEXPECTED_ERROR = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const contractNotFound = (address: Hash): Reason => {
message: `Contract ${address} was not found`,
};
};

const contractAddressInvalid = (address: Hash): Reason => {
return {
code: OpenAttestationEthereumDocumentStoreStatusCode.CONTRACT_ADDRESS_INVALID,
Expand All @@ -19,6 +20,7 @@ const contractAddressInvalid = (address: Hash): Reason => {
message: `Contract address ${address} is invalid`,
};
};

export const contractNotIssued = (merkleRoot: Hash, address: string): Reason => {
return {
code: OpenAttestationEthereumDocumentStoreStatusCode.DOCUMENT_NOT_ISSUED,
Expand All @@ -39,6 +41,27 @@ export const contractRevoked = (merkleRoot: string, address: string): Reason =>
};
};

// This function handles ALL of Ethers SERVER_ERRORs, most likely caused by HTTP 4xx or 5xx errors.
export const serverError = (): Reason => {
return {
code: OpenAttestationEthereumDocumentStoreStatusCode.SERVER_ERROR,
codeString:
OpenAttestationEthereumDocumentStoreStatusCode[OpenAttestationEthereumDocumentStoreStatusCode.SERVER_ERROR],
message: `Unable to connect to the Ethereum network, please try again later`,
};
};

// This function handles all INVALID_ARGUMENT errors likely due to invalid hex string,
// hex data is odd-length or incorrect data length
export const invalidArgument = (error: EthersError, address: string): Reason => {
return {
code: OpenAttestationEthereumDocumentStoreStatusCode.INVALID_ARGUMENT,
codeString:
OpenAttestationEthereumDocumentStoreStatusCode[OpenAttestationEthereumDocumentStoreStatusCode.INVALID_ARGUMENT],
message: `Error with smart contract ${address}: ${error.reason}`,
};
};

export const getErrorReason = (error: EthersError, address: string): Reason | null => {
const reason = error.reason && Array.isArray(error.reason) ? error.reason[0] : error.reason ?? "";
if (
Expand All @@ -55,7 +78,12 @@ export const getErrorReason = (error: EthersError, address: string): Reason | nu
(reason.toLowerCase() === "invalid address".toLowerCase() && error.code === errors.INVALID_ARGUMENT)
) {
return contractAddressInvalid(address);
} else if (error.code === errors.SERVER_ERROR) {
return serverError();
} else if (error.code === errors.INVALID_ARGUMENT) {
return invalidArgument(error, address);
}

return {
message: `Error with smart contract ${address}: ${error.reason}`,
code: OpenAttestationEthereumDocumentStoreStatusCode.ETHERS_UNHANDLED_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DocumentStoreFactory } from "@govtechsg/document-store";
import { DocumentStore } from "@govtechsg/document-store/src/contracts/DocumentStore";
import { Hash, VerificationFragmentType, VerificationFragment, Verifier } from "../../types/core";
import { OpenAttestationEthereumDocumentStoreStatusCode } from "../../types/error";
import { contractNotIssued, getErrorReason, contractRevoked } from "../../common/smartContract/documentStoreErrors";
import { contractNotIssued, getErrorReason, contractRevoked } from "./errors";
import { getIssuersDocumentStore, getProvider } from "../../common/utils";

interface IssuanceStatus {
Expand Down
Loading

0 comments on commit 5d301f6

Please sign in to comment.