Better error handling

Former-commit-id: 0b440d649e
restapi
Jens Pelzetter 2020-07-24 17:14:38 +02:00
parent 3add883c25
commit 703e05e33d
2 changed files with 136 additions and 88 deletions

View File

@ -110,7 +110,7 @@ export interface ApiResponse {
text(): Promise<string>; text(): Promise<string>;
} }
export interface ApiError { export class ApiError extends Error {
/** /**
* The HTTP status code reported by the API. `-1` if no status is available. * The HTTP status code reported by the API. `-1` if no status is available.
*/ */
@ -122,15 +122,25 @@ export interface ApiError {
/** /**
* The HTTP method used for the failed request. * The HTTP method used for the failed request.
*/ */
method: "get" | "post" | "put" | "delete" | "head" | "option"; method: "get" | "post" | "put" | "delete" | "head" | "options";
/**
* A error message providing (additional) details about the error.
*/
message: string;
/** /**
* The URL used in the failed request. * The URL used in the failed request.
*/ */
url: string; url: string;
constructor(
status: number,
statusText: string,
method: "get" | "post" | "put" | "delete" | "head" | "options",
message: string,
url: string
) {
super(message);
this.status = status;
this.statusText = statusText;
this.method = method;
this.url = url;
}
} }
/** /**
@ -246,22 +256,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError(
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error",
url, url
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError(
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, "`Failed to execute get: ${err}`",
url, url
}; );
} }
} }
@ -279,22 +289,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError(
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error",
url, url
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError (
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, `Failed to execute get: ${err}`,
url, url,
}; );
} }
} }
@ -312,22 +322,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError(
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error.",
url, url,
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError (
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, `Failed to execute get: ${err}`,
url, url,
}; );
} }
} }
@ -341,22 +351,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError (
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error.",
url, url,
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError (
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, `Failed to execute get: ${err}`,
url, url,
}; );
} }
} }
@ -367,22 +377,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError (
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error.",
url, url,
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError (
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, `Failed to execute get: ${err}`,
url, url,
}; );
} }
} }
@ -396,22 +406,22 @@ export class ApiClientFetchImpl implements LibreCcmApiClient {
if (response.ok) { if (response.ok) {
return new FetchResponse(response); return new FetchResponse(response);
} else { } else {
throw { throw new ApiError (
status: response.status, response.status,
statusText: response.statusText, response.statusText,
method: "get", "get",
message: "API responded with an error.", "API responded with an error.",
url, url,
}; );
} }
} catch (err) { } catch (err) {
throw { throw new ApiError(
status: -1, -1,
statusText: "n/a", "n/a",
method: "get", "get",
message: `Failed to execute get: ${err}`, `Failed to execute get: ${err}`,
url, url,
}; );
} }
} }
} }
@ -536,7 +546,15 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
resolve(apiResponse); resolve(apiResponse);
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(
new ApiError(
-1,
"n/a",
"get",
`Failed to do GET: ${error}`,
url
)
));
request.end(); request.end();
}); });
@ -575,7 +593,13 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(new ApiError(
-1,
"n/a",
"post",
`Failed to do POST: ${error}`,
url
)));
request.write(body); request.write(body);
@ -616,7 +640,13 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(new ApiError(
-1,
"n/a",
"put",
`Failed to do PUT: ${error}`,
url
)));
request.write(body); request.write(body);
@ -656,7 +686,13 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(new ApiError(
-1,
"n/a",
"delete",
`Failed to do DELETE: ${error}`,
url
)));
request.end(); request.end();
}); });
@ -696,7 +732,13 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
resolve(apiResponse); resolve(apiResponse);
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(new ApiError(
-1,
"n/a",
"head",
`Failed to do HEAD: ${error}`,
url
)));
request.end(); request.end();
}); });
@ -736,7 +778,13 @@ export class ApiClientNodeImpl implements LibreCcmApiClient {
resolve(apiResponse); resolve(apiResponse);
}); });
}); });
request.on("error", (error) => reject(error)); request.on("error", (error) => reject(new ApiError(
-1,
"n/a",
"options",
`Failed to do OPTIONS: ${error}`,
url
)));
request.end(); request.end();
}); });

View File

@ -10,7 +10,7 @@ import {
} from "./ApiClient"; } from "./ApiClient";
export * from "./entities"; export * from "./entities";
export { LibreCcmApiClient, ApiResponse, ApiError, buildUrl }; export { LibreCcmApiClient, ApiResponse, ApiError as ApiError, buildUrl };
/** /**
* Build an client for the LibreCCM RESTful API suitable for use in * Build an client for the LibreCCM RESTful API suitable for use in