From dd2efc3d78f2dfda44f8182f9638723dcb839781 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 20 Jul 2020 17:46:49 +0530 Subject: nicer HTTP helper in preparation for better error handling --- src/util/http.ts | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'src/util/http.ts') diff --git a/src/util/http.ts b/src/util/http.ts index 0ac989a17..bc054096a 100644 --- a/src/util/http.ts +++ b/src/util/http.ts @@ -14,6 +14,9 @@ TALER; see the file COPYING. If not, see */ +import { Codec } from "./codec"; +import { OperationFailedError } from "../operations/errors"; + /** * Helpers for doing XMLHttpRequest-s that are based on ES6 promises. * Allows for easy mocking for test cases. @@ -172,3 +175,115 @@ export class BrowserHttpLib implements HttpRequestLibrary { // Nothing to do } } + +export interface PostJsonRequest { + http: HttpRequestLibrary; + url: string; + body: any; + codec: Codec; +} + +/** + * Helper for making Taler-style HTTP POST requests with a JSON payload and response. + */ +export async function httpPostTalerJson( + req: PostJsonRequest, +): Promise { + const resp = await req.http.postJson(req.url, req.body); + + if (resp.status !== 200) { + let exc: OperationFailedError | undefined = undefined; + try { + const errorJson = await resp.json(); + const m = `received error response (status ${resp.status})`; + exc = new OperationFailedError({ + type: "protocol", + message: m, + details: { + httpStatusCode: resp.status, + errorResponse: errorJson, + }, + }); + } catch (e) { + const m = "could not parse response JSON"; + exc = new OperationFailedError({ + type: "network", + message: m, + details: { + status: resp.status, + }, + }); + } + throw exc; + } + let json: any; + try { + json = await resp.json(); + } catch (e) { + const m = "could not parse response JSON"; + throw new OperationFailedError({ + type: "network", + message: m, + details: { + status: resp.status, + }, + }); + } + return req.codec.decode(json); +} + + +export interface GetJsonRequest { + http: HttpRequestLibrary; + url: string; + codec: Codec; +} + +/** + * Helper for making Taler-style HTTP GET requests with a JSON payload. + */ +export async function httpGetTalerJson( + req: GetJsonRequest, +): Promise { + const resp = await req.http.get(req.url); + + if (resp.status !== 200) { + let exc: OperationFailedError | undefined = undefined; + try { + const errorJson = await resp.json(); + const m = `received error response (status ${resp.status})`; + exc = new OperationFailedError({ + type: "protocol", + message: m, + details: { + httpStatusCode: resp.status, + errorResponse: errorJson, + }, + }); + } catch (e) { + const m = "could not parse response JSON"; + exc = new OperationFailedError({ + type: "network", + message: m, + details: { + status: resp.status, + }, + }); + } + throw exc; + } + let json: any; + try { + json = await resp.json(); + } catch (e) { + const m = "could not parse response JSON"; + throw new OperationFailedError({ + type: "network", + message: m, + details: { + status: resp.status, + }, + }); + } + return req.codec.decode(json); +} -- cgit v1.2.3