diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-07-20 17:46:49 +0530 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-07-20 17:46:49 +0530 |
commit | dd2efc3d78f2dfda44f8182f9638723dcb839781 (patch) | |
tree | 9cfbd31607f044fb80da80d8f740ae5eaa21a2f4 /src/util/http.ts | |
parent | 5a8931d90320ebc8454969ea133c48b6998ad60a (diff) | |
download | wallet-core-dd2efc3d78f2dfda44f8182f9638723dcb839781.tar.xz |
nicer HTTP helper in preparation for better error handling
Diffstat (limited to 'src/util/http.ts')
-rw-r--r-- | src/util/http.ts | 115 |
1 files changed, 115 insertions, 0 deletions
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 <http://www.gnu.org/licenses/> */ +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<RespType> { + http: HttpRequestLibrary; + url: string; + body: any; + codec: Codec<RespType>; +} + +/** + * Helper for making Taler-style HTTP POST requests with a JSON payload and response. + */ +export async function httpPostTalerJson<RespType>( + req: PostJsonRequest<RespType>, +): Promise<RespType> { + 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<RespType> { + http: HttpRequestLibrary; + url: string; + codec: Codec<RespType>; +} + +/** + * Helper for making Taler-style HTTP GET requests with a JSON payload. + */ +export async function httpGetTalerJson<RespType>( + req: GetJsonRequest<RespType>, +): Promise<RespType> { + 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); +} |