Use Error subclasses instead of throwing strings

Jens Pelzetter 2020-08-14 16:42:39 +02:00
parent 676156d790
commit 6510eb65cb
2 changed files with 257 additions and 110 deletions

View File

@ -1,4 +1,6 @@
import { import {
ApiClientError,
ApiError,
ApiResponse, ApiResponse,
LibreCcmApiClient, LibreCcmApiClient,
} from "@libreccm/ccm-apiclient-commons"; } from "@libreccm/ccm-apiclient-commons";
@ -20,10 +22,9 @@ export class ImExportClient {
} }
async listImports(): Promise<ImportManifest[]> { async listImports(): Promise<ImportManifest[]> {
const url = `${this.#IMEXPORT_API_PREFIX}/imports`;
try { try {
const response: ApiResponse = await this.#apiClient.get( const response: ApiResponse = await this.#apiClient.get(url);
`${this.#IMEXPORT_API_PREFIX}/imports`
);
if (response.ok) { if (response.ok) {
const records: Record< const records: Record<
@ -35,28 +36,49 @@ export class ImExportClient {
buildImportManifestFromRecord(record) buildImportManifestFromRecord(record)
); );
} else { } else {
throw `Failed to list available import archives: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"get",
`Failed to list available import archives`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to list available import archives: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to list available import archives: ${err}`
);
}
} }
} }
async importArchive(importName: string): Promise<void> { async importArchive(importName: string): Promise<void> {
const url = `${this.#IMEXPORT_API_PREFIX}/imports/${importName}`;
try { try {
const response: ApiResponse = await this.#apiClient.post( const response: ApiResponse = await this.#apiClient.post(url);
`${this.#IMEXPORT_API_PREFIX}/imports/${importName}`
);
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to import archive ${importName}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"post",
`Failed to import archive ${importName}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to import archive ${importName}: ${err}`; if (err instanceof ApiClientError) {
throw err;
} else {
throw new ApiClientError(
`Failed to import archive ${importName}: ${err}`
);
}
} }
} }
@ -64,22 +86,36 @@ export class ImExportClient {
exportName: string, exportName: string,
entityIds: string[] entityIds: string[]
): Promise<void> { ): Promise<void> {
const url = `${this.#IMEXPORT_API_PREFIX}/exports/${exportName}`;
try { try {
const response: ApiResponse = await this.#apiClient.post( const response: ApiResponse = await this.#apiClient.post(
`${this.#IMEXPORT_API_PREFIX}/exports/${exportName}`, url,
JSON.stringify(entityIds) JSON.stringify(entityIds)
); );
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to export entities throw new ApiError(
${entityIds.join(", ")} as ${exportName}: response.status,
${response.status} ${response.statusText}`; response.statusText,
"post",
`Failed to export entities ${entityIds.join(
", "
)} as ${exportName}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to export entities if (err instanceof ApiError) {
${entityIds.join(", ")} as ${exportName}: ${err}`; throw err;
} else {
throw new ApiClientError(
`Failed to export entities ${entityIds.join(
", "
)} as ${exportName}: ${err}`
);
}
} }
} }
} }

View File

@ -2,6 +2,8 @@ import {
ApiResponse, ApiResponse,
LibreCcmApiClient, LibreCcmApiClient,
ListView, ListView,
ApiError,
ApiClientError,
} from "@libreccm/ccm-apiclient-commons"; } from "@libreccm/ccm-apiclient-commons";
import { buildIdentifierParam } from "@libreccm/ccm-apiclient-commons"; import { buildIdentifierParam } from "@libreccm/ccm-apiclient-commons";
@ -31,14 +33,12 @@ export class RolesApiClient {
} }
async getRoles(limit: number, offset: number): Promise<ListView<Role>> { async getRoles(limit: number, offset: number): Promise<ListView<Role>> {
const url = this.#ROLES_API_PREFIX;
try { try {
const response: ApiResponse = await this.#apiClient.get( const response: ApiResponse = await this.#apiClient.get(url, {
this.#ROLES_API_PREFIX,
{
limit: limit.toString(), limit: limit.toString(),
offset: offset.toString(), offset: offset.toString(),
} });
);
if (response.ok) { if (response.ok) {
const result: Record< const result: Record<
string, string,
@ -59,35 +59,52 @@ export class RolesApiClient {
offset: result.offset as number, offset: result.offset as number,
}; };
} else { } else {
throw `Failed to get roles: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"get",
`Failed to get roles`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to get roles: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(`Failed to get roles: ${err}`);
}
} }
} }
async getRole(roleIdentifier: string): Promise<Role> { async getRole(roleIdentifier: string): Promise<Role> {
try {
const roleParam: string = buildIdentifierParam(roleIdentifier); const roleParam: string = buildIdentifierParam(roleIdentifier);
const url = `${this.#ROLES_API_PREFIX}/${roleParam}`;
const response: ApiResponse = await this.#apiClient.get( try {
`${this.#ROLES_API_PREFIX}/${roleParam}` const response: ApiResponse = await this.#apiClient.get(url);
);
if (response.ok) { if (response.ok) {
return buildRoleFromRecord( return buildRoleFromRecord(
(await response.json()) as Record<string, unknown> (await response.json()) as Record<string, unknown>
); );
} else { } else {
throw `Failed to get role ${roleIdentifier}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"get",
`Failed to get role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to get role: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(`Failed to get role: ${err}`);
}
} }
} }
async addRole(role: Role): Promise<string> { async addRole(role: Role): Promise<string> {
const url = `${this.#ROLES_API_PREFIX}`;
try { try {
const response: ApiResponse = await this.#apiClient.post( const response: ApiResponse = await this.#apiClient.post(
`${this.#ROLES_API_PREFIX}`, `${this.#ROLES_API_PREFIX}`,
@ -96,48 +113,81 @@ export class RolesApiClient {
if (response.ok) { if (response.ok) {
return role.name; return role.name;
} else { } else {
throw `Failed to add role ${role.name}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"post",
`Failed to add role ${role.name}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to add role ${role.name}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to add role ${role.name}: ${err}`
);
}
} }
} }
async updateRole(roleIdentifier: string, role: Role): Promise<void> { async updateRole(roleIdentifier: string, role: Role): Promise<void> {
const url = `${this.#ROLES_API_PREFIX}/${buildIdentifierParam(
roleIdentifier
)}`;
try { try {
const response: ApiResponse = await this.#apiClient.put( const response: ApiResponse = await this.#apiClient.put(
`${this.#ROLES_API_PREFIX}/${buildIdentifierParam( url,
roleIdentifier
)}`,
JSON.stringify(role) JSON.stringify(role)
); );
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to update role ${roleIdentifier}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"put",
`Failed to update role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to update role ${roleIdentifier}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to update role ${roleIdentifier}: ${err}`
);
}
} }
} }
async deleteRole(roleIdentifier: string): Promise<void> { async deleteRole(roleIdentifier: string): Promise<void> {
try { const url = `${this.#ROLES_API_PREFIX}/${buildIdentifierParam(
const response: ApiResponse = await this.#apiClient.delete(
`${this.#ROLES_API_PREFIX}/${buildIdentifierParam(
roleIdentifier roleIdentifier
)}` )}`;
); try {
const response: ApiResponse = await this.#apiClient.delete(url);
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to delete role ${name}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"delete",
`Failed to delete role ${name}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to delete role ${name}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to delete role ${name}: ${err}`
);
}
} }
} }
@ -146,16 +196,14 @@ export class RolesApiClient {
limit: number, limit: number,
offset: number offset: number
): Promise<ListView<RolePartyMembership>> { ): Promise<ListView<RolePartyMembership>> {
const url = `${this.#ROLES_API_PREFIX}/${buildIdentifierParam(
roleIdentifier
)}/members`;
try { try {
const roleParam: string = buildIdentifierParam(roleIdentifier); const response: ApiResponse = await this.#apiClient.get(url, {
const response: ApiResponse = await this.#apiClient.get(
`${this.#ROLES_API_PREFIX}/${roleParam}/members`,
{
limit: limit.toString(), limit: limit.toString(),
offset: offset.toString(), offset: offset.toString(),
} });
);
if (response.ok) { if (response.ok) {
const result: Record< const result: Record<
@ -177,11 +225,22 @@ export class RolesApiClient {
offset: result.offset as number, offset: result.offset as number,
}; };
} else { } else {
throw `Failed to get members of role ${roleIdentifier}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"get",
`Failed to get members of role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to get members of role ${roleIdentifier}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get members of role ${roleIdentifier}: ${err}`
);
}
} }
} }
@ -189,22 +248,32 @@ export class RolesApiClient {
roleIdentifier: string | number, roleIdentifier: string | number,
userIdentifier: string | number userIdentifier: string | number
): Promise<void> { ): Promise<void> {
try {
const roleParam = buildIdentifierParam(roleIdentifier); const roleParam = buildIdentifierParam(roleIdentifier);
const memberParam = buildIdentifierParam(userIdentifier); const memberParam = buildIdentifierParam(userIdentifier);
const response: ApiResponse = await this.#apiClient.put( const url = `${
`${this.#ROLES_API_PREFIX}/${roleParam}/members/${memberParam}` this.#ROLES_API_PREFIX
); }/${roleParam}/members/${memberParam}`;
try {
const response: ApiResponse = await this.#apiClient.put(url);
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to add user ${userIdentifier} to throw new ApiError(
role ${roleIdentifier}: response.status,
${response.status} ${response.statusText}`; response.statusText,
"put",
`Failed to add user ${userIdentifier} to role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to add user ${userIdentifier} to if (err instanceof ApiError) {
role ${roleIdentifier}: ${err}`; throw err;
} else {
throw new ApiClientError(
`Failed to add user ${userIdentifier} to role ${roleIdentifier}: ${err}`
);
}
} }
} }
@ -212,22 +281,32 @@ export class RolesApiClient {
roleIdentifier: string | number, roleIdentifier: string | number,
userIdentifier: string | number userIdentifier: string | number
): Promise<void> { ): Promise<void> {
try {
const roleParam = buildIdentifierParam(roleIdentifier); const roleParam = buildIdentifierParam(roleIdentifier);
const memberParam = buildIdentifierParam(userIdentifier); const memberParam = buildIdentifierParam(userIdentifier);
const response: ApiResponse = await this.#apiClient.delete( const url = `${
`${this.#ROLES_API_PREFIX}/${roleParam}/members/${memberParam}` this.#ROLES_API_PREFIX
); }/${roleParam}/members/${memberParam}`;
try {
const response: ApiResponse = await this.#apiClient.delete(url);
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to remove user ${userIdentifier} from throw new ApiError(
role ${roleIdentifier}: response.status,
${response.status} ${response.statusText}`; response.statusText,
"delete",
`Failed to remove user ${userIdentifier} from role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to remote user ${userIdentifier} from if (err instanceof ApiError) {
role ${roleIdentifier}: ${err}`; throw err;
} else {
throw new ApiClientError(
`Failed to remote user ${userIdentifier} from role ${roleIdentifier}: ${err}`
);
}
} }
} }
@ -236,16 +315,14 @@ export class RolesApiClient {
limit: number, limit: number,
offset: number offset: number
): Promise<ListView<RolePermission>> { ): Promise<ListView<RolePermission>> {
try {
const roleParam: string = buildIdentifierParam(roleIdentifier); const roleParam: string = buildIdentifierParam(roleIdentifier);
const roleParam: string = buildIdentifierParam(roleIdentifier);
const response: ApiResponse = await this.#apiClient.get( const url = `${this.#ROLES_API_PREFIX}/${roleParam}/permissions`;
`${this.#ROLES_API_PREFIX}/${roleParam}/permissions`, try {
{ const response: ApiResponse = await this.#apiClient.get(url, {
limit: limit.toString(), limit: limit.toString(),
offset: offset.toString(), offset: offset.toString(),
} });
);
if (response.ok) { if (response.ok) {
const result: Record< const result: Record<
string, string,
@ -266,11 +343,22 @@ export class RolesApiClient {
offset: result.offset as number, offset: result.offset as number,
}; };
} else { } else {
throw `Failed to get permissions of role ${roleIdentifier}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"get",
`Failed to get permissions of role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to get permissions of role ${roleIdentifier}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to get permissions of role ${roleIdentifier}: ${err}`
);
}
} }
} }
@ -278,21 +366,32 @@ export class RolesApiClient {
roleIdentifier: string, roleIdentifier: string,
permission: RolePermission permission: RolePermission
): Promise<void> { ): Promise<void> {
try {
const roleParam: string = buildIdentifierParam(roleIdentifier); const roleParam: string = buildIdentifierParam(roleIdentifier);
const url = `${this.#ROLES_API_PREFIX}/${roleParam}/permissions`;
try {
const response: ApiResponse = await this.#apiClient.post( const response: ApiResponse = await this.#apiClient.post(
`${this.#ROLES_API_PREFIX}/${roleParam}/permissions`, url,
JSON.stringify(permission) JSON.stringify(permission)
); );
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to add permission to role ${roleIdentifier}: throw new ApiError(
${response.status} ${response.statusText}`; response.status,
response.statusText,
"post",
`Failed to add permission to role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to add permission to role ${roleIdentifier}: ${err}`; if (err instanceof ApiError) {
throw err;
} else {
throw new ApiClientError(
`Failed to add permission to role ${roleIdentifier}: ${err}`
);
}
} }
} }
@ -300,9 +399,12 @@ export class RolesApiClient {
roleIdentifier: string | number, roleIdentifier: string | number,
permissionIdentifier: string | number permissionIdentifier: string | number
): Promise<void> { ): Promise<void> {
try {
const roleParam = buildIdentifierParam(roleIdentifier); const roleParam = buildIdentifierParam(roleIdentifier);
const permissionParam = buildIdentifierParam(permissionIdentifier); const permissionParam = buildIdentifierParam(permissionIdentifier);
const url = `${
this.#ROLES_API_PREFIX
}/${roleParam}/permissions/${permissionParam}`;
try {
const response: ApiResponse = await this.#apiClient.delete( const response: ApiResponse = await this.#apiClient.delete(
`${ `${
this.#ROLES_API_PREFIX this.#ROLES_API_PREFIX
@ -311,13 +413,22 @@ export class RolesApiClient {
if (response.ok) { if (response.ok) {
return; return;
} else { } else {
throw `Failed to remove permission ${permissionIdentifier} from throw new ApiError(
role ${roleIdentifier}: response.status,
${response.status} ${response.statusText}`; response.statusText,
"delete",
`Failed to remove permission ${permissionIdentifier} from role ${roleIdentifier}`,
url
);
} }
} catch (err) { } catch (err) {
throw `Failed to remote permission ${permissionIdentifier} from if (err instanceof ApiError) {
role ${roleIdentifier}: ${err}`; throw err;
} else {
throw new ApiClientError(
`Failed to remote permission ${permissionIdentifier} from role ${roleIdentifier}: ${err}`
);
}
} }
} }
} }