Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(connector-fabric): reusable error handler in REST endpoints #3423

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
IEndpointAuthzOptions,
} from "@hyperledger/cactus-core-api";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";
import { DeployContractGoSourceV1Request } from "../generated/openapi/typescript-axios/index";
Expand Down Expand Up @@ -106,8 +109,8 @@ export class DeployContractGoSourceEndpointV1 implements IWebServiceEndpoint {
async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
this.log.debug(`${verbUpper} ${this.getPath()}`);

const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);
try {
const { connector } = this.opts;
const reqBody = req.body as DeployContractGoSourceV1Request;
Expand All @@ -116,10 +119,13 @@ export class DeployContractGoSourceEndpointV1 implements IWebServiceEndpoint {
res.status(HttpStatus.OK);
res.json(resBody);
} catch (ex) {
this.log.error(`${fnTag} failed to serve contract deploy request`, ex);
res.status(HttpStatus.INTERNAL_SERVER_ERROR);
res.statusMessage = ex.message;
res.json({ error: ex.stack });
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {
IEndpointAuthzOptions,
} from "@hyperledger/cactus-core-api";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";
import { DeployContractV1Request } from "../generated/openapi/typescript-axios/index";
Expand Down Expand Up @@ -87,7 +90,8 @@ export class DeployContractEndpointV1 implements IWebServiceEndpoint {
async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
this.log.debug(`${verbUpper} ${this.getPath()}`);
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
const { connector } = this.opts;
Expand All @@ -96,10 +100,13 @@ export class DeployContractEndpointV1 implements IWebServiceEndpoint {
res.status(HttpStatus.OK);
res.json(resBody);
} catch (ex) {
this.log.error(`${fnTag} failed to serve contract deploy request`, ex);
res.status(HttpStatus.INTERNAL_SERVER_ERROR);
res.statusMessage = ex.message;
res.json({ error: ex.stack });
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ export interface IGetBlockEndpointV1Options {
}

export class GetBlockEndpointV1 implements IWebServiceEndpoint {
public static readonly CLASS_NAME = "GetBlockEndpointV1";

private readonly log: Logger;

public get className(): string {
return GetBlockEndpointV1.CLASS_NAME;
}

constructor(public readonly opts: IGetBlockEndpointV1Options) {
const fnTag = "GetBlockEndpointV1#constructor()";
const fnTag = `${this.className}#constructor()`;

Checks.truthy(opts, `${fnTag} options`);
Checks.truthy(opts.connector, `${fnTag} options.connector`);
Expand Down Expand Up @@ -84,14 +90,21 @@ export class GetBlockEndpointV1 implements IWebServiceEndpoint {
}

async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = "GetBlockEndpointV1#handleRequest()";
this.log.debug(`POST ${this.getPath()}`);
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
res.status(200).send(await this.opts.connector.getBlock(req.body));
} catch (error) {
const errorMsg = `Crash while serving ${fnTag}`;
handleRestEndpointException({ errorMsg, log: this.log, error, res });
} catch (ex) {
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {

import OAS from "../../json/openapi.json";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";

Expand All @@ -28,12 +31,18 @@ export interface IGetPrometheusExporterMetricsEndpointV1Options {
export class GetPrometheusExporterMetricsEndpointV1
implements IWebServiceEndpoint
{
public static readonly CLASS_NAME = "GetPrometheusExporterMetricsEndpointV1";

private readonly log: Logger;

public get className(): string {
return GetPrometheusExporterMetricsEndpointV1.CLASS_NAME;
}

constructor(
public readonly opts: IGetPrometheusExporterMetricsEndpointV1Options,
) {
const fnTag = "GetPrometheusExporterMetricsEndpointV1#constructor()";
const fnTag = `${this.className}#constructor()`;

Checks.truthy(opts, `${fnTag} options`);
Checks.truthy(opts.connector, `${fnTag} options.connector`);
Expand Down Expand Up @@ -83,19 +92,23 @@ export class GetPrometheusExporterMetricsEndpointV1
}

async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = "GetPrometheusExporterMetrics#handleRequest()";
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
this.log.debug(`${verbUpper} ${this.getPath()}`);
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
const resBody = await this.opts.connector.getPrometheusExporterMetrics();
res.status(200);
res.send(resBody);
} catch (ex) {
this.log.error(`${fnTag} failed to serve request`, ex);
res.status(500);
res.statusMessage = ex.message;
res.json({ error: ex.stack });
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
IEndpointAuthzOptions,
} from "@hyperledger/cactus-core-api";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";
import { RunTransactionRequest } from "../generated/openapi/typescript-axios";
Expand All @@ -28,10 +31,16 @@ export interface IRunTransactionEndpointV1Options {
export class GetTransactionReceiptByTxIDEndpointV1
implements IWebServiceEndpoint
{
public static readonly CLASS_NAME = "GetTransactionReceiptByTxIDEndpointV1";

private readonly log: Logger;

public get className(): string {
return GetTransactionReceiptByTxIDEndpointV1.CLASS_NAME;
}

constructor(public readonly opts: IRunTransactionEndpointV1Options) {
const fnTag = "GetTransactionReceiptByTxIDEndpointV1#constructor()";
const fnTag = `${this.className}#constructor()`;

Checks.truthy(opts, `${fnTag} options`);
Checks.truthy(opts.connector, `${fnTag} options.connector`);
Expand Down Expand Up @@ -84,8 +93,10 @@ export class GetTransactionReceiptByTxIDEndpointV1
}

async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = "GetTransactionReceiptByTxIDEndpointV1#handleRequest()";
this.log.debug(`POST ${this.getPath()}`);
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
const reqBody = req.body as RunTransactionRequest;
Expand All @@ -94,10 +105,13 @@ export class GetTransactionReceiptByTxIDEndpointV1
res.status(200);
res.json(resBody);
} catch (ex) {
this.log.error(`${fnTag} failed to serve request`, ex);
res.status(500);
res.statusMessage = ex.message;
res.json({ error: ex.stack });
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
LogLevelDesc,
Checks,
IAsyncProvider,
safeStringifyException,
} from "@hyperledger/cactus-common";

import {
Expand All @@ -15,7 +14,10 @@ import {
IEndpointAuthzOptions,
} from "@hyperledger/cactus-core-api";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";
import OAS from "../../json/openapi.json";
Expand All @@ -28,13 +30,18 @@ export interface IRunDelegatedSignTransactionEndpointV1Options {
export class RunDelegatedSignTransactionEndpointV1
implements IWebServiceEndpoint
{
public static readonly CLASS_NAME = "RunDelegatedSignTransactionEndpointV1";

private readonly log: Logger;

public get className(): string {
return RunDelegatedSignTransactionEndpointV1.CLASS_NAME;
}

constructor(
public readonly opts: IRunDelegatedSignTransactionEndpointV1Options,
) {
const fnTag = "RunDelegatedSignTransactionEndpointV1#constructor()";

const fnTag = `${this.className}#constructor()`;
Checks.truthy(opts, `${fnTag} options`);
Checks.truthy(opts.connector, `${fnTag} options.connector`);

Expand Down Expand Up @@ -84,18 +91,22 @@ export class RunDelegatedSignTransactionEndpointV1
}

async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = "RunDelegatedSignTransactionEndpointV1#handleRequest()";
this.log.debug(`POST ${this.getPath()}`);
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
res
.status(200)
.json(await this.opts.connector.transactDelegatedSign(req.body));
} catch (error) {
this.log.error(`Crash while serving ${fnTag}`, error);
res.status(500).json({
message: "Internal Server Error",
error: safeStringifyException(error),
} catch (ex) {
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
LogLevelDesc,
Checks,
IAsyncProvider,
safeStringifyException,
} from "@hyperledger/cactus-common";

import {
Expand All @@ -15,7 +14,10 @@ import {
IEndpointAuthzOptions,
} from "@hyperledger/cactus-core-api";

import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";
import {
handleRestEndpointException,
registerWebServiceEndpoint,
} from "@hyperledger/cactus-core";

import { PluginLedgerConnectorFabric } from "../plugin-ledger-connector-fabric";
import OAS from "../../json/openapi.json";
Expand All @@ -26,10 +28,16 @@ export interface IRunTransactionEndpointV1Options {
}

export class RunTransactionEndpointV1 implements IWebServiceEndpoint {
public static readonly CLASS_NAME = "RunTransactionEndpointV1";

private readonly log: Logger;

public get className(): string {
return RunTransactionEndpointV1.CLASS_NAME;
}

constructor(public readonly opts: IRunTransactionEndpointV1Options) {
const fnTag = "RunTransactionEndpointV1#constructor()";
const fnTag = `${this.className}#constructor()`;

Checks.truthy(opts, `${fnTag} options`);
Checks.truthy(opts.connector, `${fnTag} options.connector`);
Expand Down Expand Up @@ -80,16 +88,20 @@ export class RunTransactionEndpointV1 implements IWebServiceEndpoint {
}

async handleRequest(req: Request, res: Response): Promise<void> {
const fnTag = "RunTransactionEndpointV1#handleRequest()";
this.log.debug(`POST ${this.getPath()}`);
const fnTag = `${this.className}#handleRequest()`;
const verbUpper = this.getVerbLowerCase().toUpperCase();
const reqTag = `${verbUpper} ${this.getPath()}`;
this.log.debug(reqTag);

try {
res.status(200).json(await this.opts.connector.transact(req.body));
} catch (error) {
this.log.error(`Crash while serving ${fnTag}`, error);
res.status(500).json({
message: "Internal Server Error",
error: safeStringifyException(error),
} catch (ex) {
const errorMsg = `${fnTag} request handler fn crashed for: ${reqTag}`;
await handleRestEndpointException({
errorMsg,
log: this.log,
error: ex,
res,
});
}
}
Expand Down
Loading