Skip to content

Commit

Permalink
refactor(connector-fabric): reusable error handler in REST endpoints
Browse files Browse the repository at this point in the history
1. Error-handling : Updates to the catch block of the Rest API endpoints of fabric package by importing the utility
function handleRestEndpointException from cactus-core package that differentiates the user/developer errors.
2. Minor code changes in the endpoints like adding the functions and formulating the error messages.

Signed-off-by: ArchanaArige <49356222+ArchanaArige@users.noreply.github.com>
  • Loading branch information
ArchanaArige committed Jul 19, 2024
1 parent c867a9f commit 07e1574
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 64 deletions.
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,8 @@ 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,8 @@ 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,17 @@ 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 @@ -26,14 +29,19 @@ export interface IGetPrometheusExporterMetricsEndpointV1Options {
}

export class GetPrometheusExporterMetricsEndpointV1
implements IWebServiceEndpoint
{
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 +91,18 @@ 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 @@ -26,12 +29,17 @@ export interface IRunTransactionEndpointV1Options {
}

export class GetTransactionReceiptByTxIDEndpointV1
implements IWebServiceEndpoint
{
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 +92,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 +104,8 @@ 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,11 @@ 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,15 +29,19 @@ export interface IRunDelegatedSignTransactionEndpointV1Options {
}

export class RunDelegatedSignTransactionEndpointV1
implements IWebServiceEndpoint
{
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,19 +91,18 @@ 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 });
}
}
}
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,17 +88,16 @@ 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 });
}
}
}

0 comments on commit 07e1574

Please sign in to comment.