Skip to content

Commit

Permalink
refactor(cardano-graphql): deserialize and throw domain errors in TxS…
Browse files Browse the repository at this point in the history
…ubmitHttpProvider

- Note: While this rehydrates errors, until
sindresorhus/serialize-error#48, the type precision is lost.
The error.name can be used to differentiate the type for now.
- Also improves tests to avoid false-positives
- Fixes JSDoc references
  • Loading branch information
rhyslbw authored and mkazlauskas committed Mar 23, 2022
1 parent 24b43b3 commit deb8aaf
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
4 changes: 3 additions & 1 deletion packages/cardano-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"test:debug": "DEBUG=true yarn test"
},
"devDependencies": {
"@cardano-sdk/cardano-graphql-services": "0.2.0",
"@graphql-codegen/cli": "~2.5.0",
"@graphql-codegen/typescript": "~2.4.3",
"@graphql-codegen/typescript-graphql-request": "~4.3.4",
Expand All @@ -43,7 +44,8 @@
"graphql": "~15.6.1",
"graphql-request": "npm:graphql-request-configurable-serializer@4.0.0",
"graphql-tag": "2.12.5",
"json-bigint": "~1.0.0"
"json-bigint": "~1.0.0",
"serialize-error": "^8"
},
"files": [
"dist/*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { ProviderError, ProviderFailure, TxSubmitProvider } from '@cardano-sdk/core';
import {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Cardano,
ProviderError,
ProviderFailure,
TxSubmitProvider
} from '@cardano-sdk/core';
import { deserializeError } from 'serialize-error';
import got from 'got';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import type ConnectionConfig from '@cardano-sdk/cardano-graphql-services';

/**
* Connect to a TxSubmitHttpServer instance
*
* @param {ConnectionConfig} connectionConfig Service connection configuration
* @returns {TxSubmitProvider} TxSubmitProvider
* @throws {TxSubmission.errors}
* @throws {Cardano.TxSubmissionErrors}
*/
export const txSubmitHttpProvider = (connectionConfig: { url: string }): TxSubmitProvider => ({
async healthCheck() {
Expand All @@ -27,6 +38,12 @@ export const txSubmitHttpProvider = (connectionConfig: { url: string }): TxSubmi
headers: { 'Content-Type': 'application/cbor' }
});
} catch (error) {
const domainErrors = JSON.parse(error.response.body) as string | string[];
if (domainErrors !== undefined && Array.isArray(domainErrors)) {
throw domainErrors.map((e: string) => deserializeError(e));
} else if (domainErrors !== undefined) {
throw deserializeError(domainErrors);
}
throw new ProviderError(ProviderFailure.Unknown, error);
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/cardano-graphql/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"rootDir": "."
},
"references": [
{ "path": "../../cardano-graphql-services/src" },
{ "path": "../../core/src" }
]
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Cardano } from '@cardano-sdk/core';
import { serializeError } from 'serialize-error';
import { txSubmitHttpProvider } from '../../src';
import got from 'got';

const url = 'http://localhost:3000';
const url = 'http://some-hostname:3000';

describe('txSubmitHttpProvider', () => {
describe('healthCheck', () => {
it('is not ok if cannot connect', async () => {
const provider = txSubmitHttpProvider({ url });
const res = await provider.healthCheck();
expect(res).toEqual({ ok: false });
await expect(provider.healthCheck()).resolves.toEqual({ ok: false });
});
describe('mocked', () => {
beforeAll(() => {
Expand All @@ -22,21 +23,39 @@ describe('txSubmitHttpProvider', () => {
it('is ok if 200 response body is { ok: true }', async () => {
got.get = jest.fn().mockResolvedValue({ body: JSON.stringify({ ok: true }) });
const provider = txSubmitHttpProvider({ url });
const res = await provider.healthCheck();
expect(res).toEqual({ ok: true });
await expect(provider.healthCheck()).resolves.toEqual({ ok: true });
});

it('is not ok if 200 response body is { ok: false }', async () => {
got.get = jest.fn().mockResolvedValue({ body: JSON.stringify({ ok: false }) });
const provider = txSubmitHttpProvider({ url });
const res = await provider.healthCheck();
expect(res).toEqual({ ok: false });
await expect(provider.healthCheck()).resolves.toEqual({ ok: false });
});
});
});
it('submitTx', async () => {
got.post = jest.fn().mockResolvedValue('');
const provider = txSubmitHttpProvider({ url });
await expect(provider.submitTx(new Uint8Array())).resolves;
describe('submitTx', () => {
it('resolves if successful', async () => {
got.post = jest.fn().mockResolvedValue('');
const provider = txSubmitHttpProvider({ url });
await expect(provider.submitTx(new Uint8Array())).resolves;
});
it('rehydrates errors, although only as base Error class', async () => {
const errors = [new Cardano.TxSubmissionErrors.BadInputsError({ badInputs: [] })];
try {
got.post = jest.fn().mockRejectedValue({
response: {
body: JSON.stringify(errors.map((e) => serializeError(e)))
}
});
const provider = txSubmitHttpProvider({ url });
await provider.submitTx(new Uint8Array());
throw new Error('fail');
} catch (error) {
// https://github.com/sindresorhus/serialize-error/issues/48
// expect(error[0]).toBeInstanceOf(Cardano.TxSubmissionErrors.BadInputsError);
expect(error[0]).toBeInstanceOf(Error);
expect(error[0].name).toBe('BadInputsError');
}
});
});
});

0 comments on commit deb8aaf

Please sign in to comment.