Skip to content

Commit

Permalink
refactor(idea/backend): backend errors (#1565)
Browse files Browse the repository at this point in the history
  • Loading branch information
osipov-mit authored May 24, 2024
1 parent ad7a65a commit db48001
Show file tree
Hide file tree
Showing 32 changed files with 186 additions and 147 deletions.
2 changes: 0 additions & 2 deletions idea/api-gateway/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { logger } from '@gear-js/common';

import { RMQService } from './rmq';
import { Server, changeStatus } from './server';

Expand Down
10 changes: 7 additions & 3 deletions idea/api-gateway/src/middleware/check-genesis.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ export async function checkGenesisMiddleware(
next: NextFunction,
) {
if (Array.isArray(body)) {
const isExistGenesis = body.every((value) => metaStorageMethods.includes(body.method) || value.params.genesis);
for (let i = 0; i < body.length; i++) {
if (metaStorageMethods.includes(body[i].method) || body[i]?.__error) {
continue;
}

if (!isExistGenesis) {
return res.send(getResponse(body, JSONRPC_ERRORS.NoGenesisFound.name));
if (!body[i]?.params?.genesis) {
body[i] = { __error: getResponse(body[i], JSONRPC_ERRORS.NoGenesisFound.name) };
}
}
} else {
if (metaStorageMethods.includes(body.method)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { IRpcRequest, JSONRPC_ERRORS, logger } from '@gear-js/common';

export async function validateJsonRpcRequestMiddleware({ body }: Request, res: Response, next: NextFunction) {
if (Array.isArray(body)) {
for (const request of body) {
if (!isValidRequestParams(request)) {
return res.send(getInvalidParamsResponse(request));
if (body.length === 0) {
return res.send(getInvalidRequestResponse(null));
}
for (let i = 0; i < body.length; i++) {
if (!isValidRequestParams(body[i])) {
body[i] = { __error: getInvalidRequestResponse(body[i]) };
}
}
} else {
if (!isValidRequestParams(body)) {
return res.send(getInvalidParamsResponse(body));
return res.send(getInvalidRequestResponse(body));
}
}

Expand All @@ -20,14 +23,14 @@ export async function validateJsonRpcRequestMiddleware({ body }: Request, res: R
const isValidRequestParams = ({ id, method, jsonrpc, params }: IRpcRequest): boolean =>
!!id && !!method && !!jsonrpc && !!params;

function getInvalidParamsResponse(req: IRpcRequest) {
logger.info('Invalid params error', { req });
function getInvalidRequestResponse(req: IRpcRequest) {
logger.info('Invalid request error', { req });

const error = JSONRPC_ERRORS.InvalidParams;
const error = JSONRPC_ERRORS.InvalidRequest;

return {
jsonrpc: '2.0',
id: req.id || null,
id: req?.id || null,
error: {
message: error.message,
code: error.code,
Expand Down
26 changes: 22 additions & 4 deletions idea/api-gateway/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
JSONRPC_ERRORS,
API_GATEWAY_METHODS,
logger,
IRpcRequestAfterMiddleware,
} from '@gear-js/common';
import { nanoid } from 'nanoid';
import express, { Express, Request, Response } from 'express';
Expand Down Expand Up @@ -118,14 +119,31 @@ export class Server {
return this.app.listen(config.server.port, () => logger.info(`App successfully run on the ${config.server.port}`));
}

private async handleRequest(rpcBodyRequest: IRpcRequest | IRpcRequest[]): Promise<IRpcResponse | IRpcResponse[]> {
private async handleRequest(
rpcBodyRequest: IRpcRequest | IRpcRequestAfterMiddleware[],
): Promise<IRpcResponse | IRpcResponse[]> {
if (Array.isArray(rpcBodyRequest)) {
const promises = rpcBodyRequest.map((rpcBody) => {
return this.executeProcedure(rpcBody);
const promises = rpcBodyRequest.map(async (rpcBody) => {
if ('__error' in rpcBody) {
return rpcBody.__error;
} else {
try {
return await this.executeProcedure(rpcBody);
} catch (error) {
return getResponse(rpcBody, error.name in JSONRPC_ERRORS ? error.name : JSONRPC_ERRORS.InternalError.name);
}
}
});
return Promise.all(promises);
} else {
return this.executeProcedure(rpcBodyRequest);
try {
return this.executeProcedure(rpcBodyRequest);
} catch (error) {
return getResponse(
rpcBodyRequest,
error.name in JSONRPC_ERRORS ? error.name : JSONRPC_ERRORS.InternalError.name,
);
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions idea/common/src/errors/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { JSONRPC_ERRORS } from './jsonrpc-errors';

export class GearJsonRPCError extends Error {
name = 'GearJsonRPCError';
constructor(data?: string) {
super(data);
}
}

export class InvalidParamsError extends GearJsonRPCError {
name = JSONRPC_ERRORS.InvalidParams.name;
}
6 changes: 6 additions & 0 deletions idea/common/src/errors/code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { GearJsonRPCError } from './base';
import { JSONRPC_ERRORS } from './jsonrpc-errors';

export class CodeNotFound extends GearJsonRPCError {
name = JSONRPC_ERRORS.CodeNotFound.name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ export * from './message';
export * from './program';
export * from './signature';
export * from './code';
export * from './interfaces';
export * from './state';
export * from './jsonrpc-errors';
export * from './meta-storage';
export * from './base';
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export const JSONRPC_ERRORS = {
InvalidRequest: {
name: 'InvalidRequest',
code: -32600,
message: 'Invalid request',
},
MethodNotFound: {
name: 'MethodNotFound',
code: -32601,
Expand Down
File renamed without changes.
14 changes: 14 additions & 0 deletions idea/common/src/errors/meta-storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { JSONRPC_ERRORS } from './jsonrpc-errors';
import { GearJsonRPCError } from './base';

export class MetaNotFoundError extends GearJsonRPCError {
name = JSONRPC_ERRORS.MetadataNotFound.name;
}

export class InvalidMetadataError extends GearJsonRPCError {
name = JSONRPC_ERRORS.InvalidMetaHex.name;
}

export class SailsIdlNotFoundError extends GearJsonRPCError {
name = JSONRPC_ERRORS.SailsIdlNotFound.name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,3 @@ import { GearJsonRPCError } from './base';
export class ProgramNotFound extends GearJsonRPCError {
name = 'ProgramNotFound';
}

export class ProgramHasNoMeta extends GearJsonRPCError {
name = 'ProgramHasNoMeta';
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion idea/common/src/form-response.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSONRPC_ERRORS, isExistError } from './jsonrpc-errors';
import { JSONRPC_ERRORS, isExistError } from './errors/jsonrpc-errors';
import { logger } from './logger';

export function FormResponse(target: unknown, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
Expand Down
2 changes: 1 addition & 1 deletion idea/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export * from './logger';
export * from './interfaces';
export * from './enums';
export * from './form-response.decorator';
export { JSONRPC_ERRORS } from './jsonrpc-errors';
export * from './errors';
7 changes: 7 additions & 0 deletions idea/common/src/interfaces/rpc-request/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API_GATEWAY_METHODS, INDEXER_METHODS, META_STORAGE_METHODS, TEST_BALANCE_METHODS } from '../../enums';
import { IRpcResponse } from '../api-response';

export * from './indexer';
export * from './meta-storage';
Expand All @@ -10,3 +11,9 @@ export interface IRpcRequest {
method: INDEXER_METHODS | META_STORAGE_METHODS | TEST_BALANCE_METHODS | API_GATEWAY_METHODS;
params: any;
}

export interface IRpcRequestWithErrorAfterMiddleware {
__error: IRpcResponse;
}

export type IRpcRequestAfterMiddleware = IRpcRequest | IRpcRequestWithErrorAfterMiddleware;
6 changes: 0 additions & 6 deletions idea/indexer/src/common/errors/base.ts

This file was deleted.

9 changes: 0 additions & 9 deletions idea/indexer/src/common/errors/code.ts

This file was deleted.

3 changes: 0 additions & 3 deletions idea/indexer/src/common/errors/interfaces.ts

This file was deleted.

1 change: 0 additions & 1 deletion idea/indexer/src/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './constants';
export * from './enums';
export * from './types';
export * from './errors';
export * from './helpers';
3 changes: 2 additions & 1 deletion idea/indexer/src/services/code.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import {
GetAllCodeResult,
GetCodeParams,
logger,
CodeNotFound,
} from '@gear-js/common';
import { Between, DataSource, FindOptionsWhere, ILike, In, Not, Repository } from 'typeorm';

import { Code } from '../database/entities';
import { CodeNotFound, PAGINATION_LIMIT } from '../common';
import { PAGINATION_LIMIT } from '../common';

export class CodeService {
private repo: Repository<Code>;
Expand Down
3 changes: 2 additions & 1 deletion idea/indexer/src/services/message.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import {
logger,
ProgramStatus,
MessageType,
MessageNotFound,
} from '@gear-js/common';

import { Message } from '../database';
import { ProgramService } from './program.service';
import { MessagesDispatchedDataInput, MessageEntryPoint, MessageNotFound, PAGINATION_LIMIT } from '../common';
import { MessagesDispatchedDataInput, MessageEntryPoint, PAGINATION_LIMIT } from '../common';

export class MessageService {
private repo: Repository<Message>;
Expand Down
7 changes: 6 additions & 1 deletion idea/indexer/src/services/program.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import {
GetAllProgramsParams,
GetAllProgramsResult,
IProgram,
InvalidParamsError,
ProgramNotFound,
ProgramStatus,
logger,
} from '@gear-js/common';

import { ProgramNotFound } from '../common/errors';
import { Program } from '../database/entities';
import { PAGINATION_LIMIT } from '../common';

Expand All @@ -22,6 +23,10 @@ export class ProgramService {
}

public async get({ id, genesis }: FindProgramParams): Promise<Program> {
if (!id) {
throw new InvalidParamsError('Program ID is required');
}

const program = await this.repo.findOne({
where: { id, genesis },
});
Expand Down
5 changes: 3 additions & 2 deletions idea/indexer/src/services/state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import {
AddStateParams,
AddStateResult,
GetAllStateParams,
GetStateByCodeParams,
GetStateParams,
GetStatesResult,
ProgramNotFound,
StateAlreadyExists,
StateNotFound,
} from '@gear-js/common';
import { DataSource, Repository } from 'typeorm';
import { generateCodeHash, getStateMetadata } from '@gear-js/api';

import { State } from '../database';
import { ProgramNotFound, StateAlreadyExists, StateNotFound } from '../common';
import { ProgramService } from './program.service';

export class StateService {
Expand Down
14 changes: 11 additions & 3 deletions idea/meta-storage/src/service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { AddMetaDetailsParams, AddMetahashParams, GetMetaParams, logger } from '@gear-js/common';
import {
AddMetaDetailsParams,
AddMetahashParams,
GetMetaParams,
InvalidMetadataError,
InvalidParamsError,
logger,
MetaNotFoundError,
SailsIdlNotFoundError,
} from '@gear-js/common';
import { ProgramMetadata, MetadataVersion, HumanTypesRepr } from '@gear-js/api';
import { Repository } from 'typeorm';
import * as crypto from 'crypto';

import { Meta, AppDataSource, SailsIdl } from './database';
import { InvalidParamsError, MetaNotFoundError, SailsIdlNotFoundError } from './util/errors';
import { validateMetaHex } from './util/validate';
import { Code } from './database/entities/code.entity';

Expand Down Expand Up @@ -55,7 +63,7 @@ export class MetaService {
try {
metadata = ProgramMetadata.from(meta.hex);
} catch (error) {
throw new InvalidParamsError('Invalid metadata hex');
throw new InvalidMetadataError('Invalid metadata hex');
}

if (metadata.version === MetadataVersion.V1Rust) {
Expand Down
17 changes: 0 additions & 17 deletions idea/meta-storage/src/util/errors.ts

This file was deleted.

3 changes: 2 additions & 1 deletion idea/meta-storage/src/util/validate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { HexString, generateCodeHash } from '@gear-js/api';
import { InvalidMetadataError } from './errors';
import { InvalidMetadataError } from '@gear-js/common';

export function validateMetaHex(hex: HexString, hash: string) {
console.log(hex, hash, generateCodeHash(hex));
if (hash !== generateCodeHash(hex)) {
throw new InvalidMetadataError();
}
Expand Down
Loading

0 comments on commit db48001

Please sign in to comment.