错误方法:运行时错误:无效的内存地址或无指针取消引用)



我正在做一个nest.js微服务项目。控制器和服务已定义,后端运行时不会出现错误。我正在尝试使用创建一个资源(本例中为subscriptionPlan(grpurl,如下所示:

grpcurl -d '{
"name": "Test GRPC",
"code": "12312",
"description": "test",
"price": 10,
"invoicePeriod": 10,
"invoiceDuration":"DAY"
}' -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/Create

当我运行这个命令时,我得到一条错误消息:Failed to process proto source files.: could not parse given files: %!v(PANIC=Error method: runtime error: invalid memory address or nil pointer dereference)

我觉得后端/服务代码没有问题,这是项目设置的问题——也许我缺少命令行工具上的库。我检查了x代码开发工具是否已安装,所有模块依赖项也已安装。

这是我的:subscription_plan.service.ts

/* eslint-disable complexity */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { injectable } from 'inversify';
import _ from 'lodash';
import { createEverLogger } from '../../helpers/Log';
import { ErrorGenerator } from '../../shared/errors.generator';
import {
BadRequestError,
ConflictError,
NotFoundError,
ParseError,
} from '../../shared/errors.messages';
import { DatabaseService } from '../database/database.service';
import { servicesContainer } from '../inversify.config';
import { IService } from '../IService';
import { SubscriptionPlans } from './model/subscription_plan.model';
import {
DeleteSubscriptionPlanResponse,
ISubscriptionPlanService,
SubscriptionInputPayload,
SubscriptionPlan,
SubscriptionPlanFilter,
SubscriptionPlanResponse,
SubscriptionPlanUpdatePayload,
UpdateSubscriptionPlanResponse,
} from './types/subscription_plan.types';
import { subscriptionPlanCreateSchema } from './validators/subscription_plan.create.yup';
import { subscriptionPlanFilterSchema } from './validators/subscription_plan.filter.yup';
import { subscriptionPlanUpdateSchema } from './validators/subscription_plan.update.yup';
/**
* Subscription Plans Service
* CRUD operation for Subscription Plan
* @export
* @class SubscriptionPlanService
* @implements {ISubscriptionPlanService}
* @implements {IService}
*/
@injectable()
export class SubscriptionPlanService
implements ISubscriptionPlanService, IService {
private logger = createEverLogger({ name: 'SubscriptionPlanService' });
private dbService = servicesContainer.get<DatabaseService>(DatabaseService);
/**
* Create the subscription plan
*
* Returns the newly created subscription plan object with id
*
* @param {SubscriptionInputPayload} payload
* @returns {Promise<SubscriptionPlan>}
* @memberof SubscriptionPlanService
*/
async create(payload: SubscriptionInputPayload): Promise<SubscriptionPlan> {
let result: SubscriptionPlan;
try {
// Validate the payload
await subscriptionPlanCreateSchema.validate(payload, {
abortEarly: false,
});
const slug = payload.name.toLowerCase().replace(' ', '-');
// Check for existing slug
const isExist = await this.dbService.findOne<
SubscriptionPlan,
SubscriptionPlanFilter
>({ slug });
if (!_.isNil(isExist)) {
throw ConflictError(ErrorGenerator.Duplicate('Subscription Plan'));
}
// Make db call
result = await this.dbService.create<SubscriptionPlan, SubscriptionPlans>(
new SubscriptionPlans({ ...payload, slug }),
);
this.logger.debug('Subscription Plan added Successfully', result);
} catch (e) {
this.logger.error(e);
ParseError(e, ErrorGenerator.Duplicate('Subscription Plan'));
}
if (!_.isEmpty(result?.id)) {
return result;
}
throw BadRequestError(ErrorGenerator.UnableSave('Subscription Plan'));
}
/**
* Get the subscription plan by id only
* will return single object
* @param {SubscriptionPlanFilter} where
* @returns {Promise<SubscriptionPlan>}
* @memberof SubscriptionPlanService
*/
async findOne(where: SubscriptionPlanFilter): Promise<SubscriptionPlan> {
let edge: SubscriptionPlan;
try {
// Validate Input
await subscriptionPlanFilterSchema.validate(where, {
abortEarly: false,
});
// Get the subscription plan id
// TODO: Implement other filters
const id = where?.id;
if (!_.isNil(id)) {
// make db call
edge = await this.dbService.findOne<
SubscriptionPlan,
SubscriptionPlanFilter
>(new SubscriptionPlans({ id }));
}
} catch (e) {
this.logger.error(e);
ParseError(e, ErrorGenerator.NotFound('Subscription Plan'));
}
if (!_.isEmpty(edge)) {
this.logger.debug('Subscription Plan loaded Successfully', edge);
return edge;
}
throw NotFoundError(ErrorGenerator.NotFound('Subscription Plan'));
}
/**
* Get all the subscriptions plans
* with pagination
* @param {SubscriptionPlanFilter} [where]
* @returns {Promise<SubscriptionPlanResponse>}
* @memberof SubscriptionPlanService
*/
async findAll(
where?: SubscriptionPlanFilter,
): Promise<SubscriptionPlanResponse> {
// Validate the Input
let edges: SubscriptionPlan[];
let count: number; // Rows counts
let recordLimit = 10; // Pagination Limit
let recordSkip = 0; // Pagination: SKIP
// TODO
// Transform from Object to Array
// { id: SortDirection.ASC } to [ "id", "ASC"]
// for (const [key, value] of Object.entries(sortBy)) {
//   sortOrder.push([key, value]);
// }
try {
await subscriptionPlanFilterSchema.validate(where, {
abortEarly: false,
});
if (where) {
// TODO: Implement other filters
const { id, limit, skip } = where;
// isNil check for for null or undefined
if (!_.isNil(id) && !_.isNil(limit) && !_.isNil(skip)) {
// Set Limit and Skip for `page_info`
recordLimit = limit;
recordSkip = skip;
// Load the SubscriptionPlan with ID and Pagination
[edges, count] = await this.dbService.findAll<
SubscriptionPlan,
Partial<SubscriptionPlanFilter>
>(new SubscriptionPlans({ id }), recordLimit, recordSkip);
} else if (!_.isNil(limit) && !_.isNil(skip)) {
// Set Limit and Skip for `page_info`
recordLimit = limit;
recordSkip = skip;
// Load All SubscriptionPlan with default pagination
[edges, count] = await this.dbService.findAll<
SubscriptionPlan,
Partial<SubscriptionPlanFilter>
>(new SubscriptionPlans(), recordLimit, recordSkip);
} else if (!_.isNil(id)) {
// Load All SubscriptionPlan with id with default pagination
[edges, count] = await this.dbService.findAll<
SubscriptionPlan,
Partial<SubscriptionPlanFilter>
>(new SubscriptionPlans({ id }), recordLimit, recordSkip);
}
} else {
// Load All SubscriptionPlan with default pagination
[edges, count] = await this.dbService.findAll<
SubscriptionPlan,
Partial<SubscriptionPlanFilter>
>(new SubscriptionPlans(), recordLimit, recordSkip);
}
} catch (error) {
this.logger.error(error);
// Empty
ParseError(error, ErrorGenerator.NotFound('Subscription Plan'));
}
// Validate edges are not empty
if (!_.isEmpty(edges)) {
this.logger.debug('Subscription Plan loaded Successfully', edges);
return {
edges,
page_info: {
total: count,
limit: recordLimit,
skip: recordSkip,
has_more: count > recordLimit + recordSkip ? true : false,
},
};
}
throw NotFoundError(ErrorGenerator.NotFound('Subscription Plan'));
}
count(where?: SubscriptionPlanFilter): Promise<number> {
throw new Error('Method not implemented.');
}
/**
* Update the subscription plan
* by id only
* @param {SubscriptionPlanUpdatePayload} payload
* @param {SubscriptionPlanFilter} where
* @returns {Promise<UpdateSubscriptionPlanResponse>}
* @memberof SubscriptionPlanService
*/
async update(
payload: SubscriptionPlanUpdatePayload,
where: SubscriptionPlanFilter,
): Promise<UpdateSubscriptionPlanResponse> {
let modified: number;
let edges: SubscriptionPlan[];
try {
// Validate the input
await subscriptionPlanUpdateSchema.validate(
{ ...payload, ...where },
{ abortEarly: false },
);
// Check where is defined
if (where) {
const { id } = where;
// Get Subscription plan id
if (!_.isNil(id)) {
// Generate the slug
const slug = payload.name.toLowerCase().replace(' ', '-');
// Check for existing slug
const isExist = await this.dbService.findOne<
SubscriptionPlan,
SubscriptionPlanFilter
>({ slug });
// Validate the ID is not same
// Return document can have the same ID as of update
if (!_.isNil(isExist) && isExist?.id != id) {
throw ConflictError(ErrorGenerator.Duplicate('Subscription Plan'));
}
// Make db call
[edges, modified] = await this.dbService.update<
SubscriptionPlan,
Partial<SubscriptionPlan>,
SubscriptionPlanFilter
>(
new SubscriptionPlans({ ...payload, slug }),
new SubscriptionPlans({ id }),
);
this.logger.debug('Subscription Plan Update Successfully', edges);
}
}
} catch (e) {
this.logger.error(e);
ParseError(e, ErrorGenerator.Duplicate('Subscription Plan'));
}
if (modified > 0) {
// Return the update data with count
return { modified, edges };
}
throw NotFoundError(ErrorGenerator.NotFound('Subscription Plan'));
}
/**
* Delete the subscription plan
* by id only
* @param {SubscriptionPlanFilter} where
* @returns {Promise<DeleteSubscriptionPlanResponse>}
* @memberof SubscriptionPlanService
*/
async delete(
where: SubscriptionPlanFilter,
): Promise<DeleteSubscriptionPlanResponse> {
let modified: number;
let edges: SubscriptionPlan[];
try {
this.logger.info(where, 'Delete request');
// Validate the payload
await subscriptionPlanFilterSchema.validate(where, { abortEarly: false });
// Check where is defined
if (where) {
// Get the subscription plan id
const { id } = where;
if (!_.isNil(id)) {
// Make db call
[edges, modified] = await this.dbService.delete<
SubscriptionPlan,
SubscriptionPlanFilter
>(new SubscriptionPlans({ id }));
this.logger.debug('Subscription Plan deleted Successfully', edges);
}
}
} catch (e) {
this.logger.error(e);
ParseError(e, ErrorGenerator.UnableToDelete('Subscription Plan'));
}
if (modified > 0) {
return { modified, edges };
}
throw NotFoundError(ErrorGenerator.NotFound('Subscription Plan'));
}
}

这是我的service_plan.controller.ts

/* eslint-disable @typescript-eslint/no-unused-vars */
import { Controller } from '@nestjs/common';
import { GrpcMethod, RpcException } from '@nestjs/microservices';
import { HttpError } from 'http-json-errors';
import { inject, LazyServiceIdentifer } from 'inversify';
import { rpc, subscription_plan } from '../codegen/rpc';
import { SubscriptionPlanService } from '../services/SubscriptionPlan/subscription_plan.service';
import SubscriptionPlanResponse = subscription_plan.SubscriptionPlanResponse;
import SubscriptionPlanFilter = subscription_plan.SubscriptionPlanFilter;
import SubscriptionPlan = subscription_plan.SubscriptionPlan;
import DeleteSubscriptionPlanResponse = subscription_plan.DeleteSubscriptionPlanResponse;
import UpdateSubscriptionPlanResponse = subscription_plan.UpdateSubscriptionPlanResponse;
import UpdateSubscriptionPlanRequest = subscription_plan.UpdateSubscriptionPlanRequest;
import SubscriptionPlanInput = subscription_plan.SubscriptionPlanInput;
import IEmpty = rpc.IEmpty;
@Controller()
export class SubscriptionPlanController {
constructor(
@inject(new LazyServiceIdentifer(() => SubscriptionPlanService))
private readonly subscriptionPlanService: SubscriptionPlanService,
) {}
/**
* Get all subscription plans
* Test command : grpcurl -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/FindAll
* @param {IEmpty} req
* @returns {Promise<SubscriptionPlans>}
* @memberof SubscriptionPlanController
*/
@GrpcMethod('SubscriptionPlanService', 'FindAll')
async findAll(req: IEmpty): Promise<SubscriptionPlanResponse> {
try {
const obj = await this.subscriptionPlanService.findAll();
return SubscriptionPlanResponse.create(
(obj as unknown) as SubscriptionPlanResponse,
);
} catch (error) {
const errorInfo = error as HttpError;
throw new RpcException({
code: errorInfo.statusCode,
message: JSON.stringify(error),
});
}
}
/**
* Get One subscription plan
* Test command : grpcurl -d '{"id":"513-A"}' -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/FindOne
* @param {SubscriptionPlanFilter} where
* @returns {Promise<SubscriptionPlan>}
* @memberof SubscriptionPlanController
*/
@GrpcMethod('SubscriptionPlanService', 'FindOne')
async findOne(where: SubscriptionPlanFilter): Promise<SubscriptionPlan> {
try {
const id = where?.id;
const obj = await this.subscriptionPlanService.findOne({ id });
return SubscriptionPlan.create((obj as unknown) as SubscriptionPlan);
} catch (error) {
const errorInfo = error as HttpError;
throw new RpcException({
code: errorInfo.statusCode,
message: JSON.stringify(error),
});
}
}
/**
* Create subscription plan
* Test command : grpcurl -d '{
"name": "Test GRPC",
"code": "12312",
"description": "test",
"price": 10,
"invoicePeriod": 10,
"invoiceDuration":"DAY"
}' -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/Create
*
* @param {SubscriptionPlanInput} payload
* @returns {Promise<SubscriptionPlan>}
* @memberof SubscriptionPlanController
*/
@GrpcMethod('SubscriptionPlanService', 'Create')
async create(payload: SubscriptionPlanInput): Promise<SubscriptionPlan> {
try {
const obj = await this.subscriptionPlanService.create({
name: payload?.name,
price: payload?.price,
invoice_duration: payload?.invoice_duration as any,
invoice_period: payload?.invoice_period,
trail_period: payload?.trail_period,
trail_duration: payload?.trail_duration as any,
description: payload?.description,
code: payload?.code,
});
return SubscriptionPlan.create((obj as unknown) as SubscriptionPlan);
} catch (error) {
const errorInfo = error as HttpError;
throw new RpcException({
code: errorInfo.statusCode,
message: JSON.stringify(error) || error,
});
}
}
/**
* Update subscription plan
* Test command :
* grpcurl -d '{"payload":{"name":"Update Text"},"where":{"id":"97-A"}}'
* -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/Update
* @param {UpdateSubscriptionPlanRequest} data
* @returns {Promise<UpdateSubscriptionPlanResponse>}
* @memberof SubscriptionPlanController
*/
@GrpcMethod('SubscriptionPlanService', 'Update')
async update(
data: UpdateSubscriptionPlanRequest,
): Promise<UpdateSubscriptionPlanResponse> {
try {
const { payload, where } = data;
const obj = await this.subscriptionPlanService.update(
payload as any,
where,
);
return UpdateSubscriptionPlanResponse.create(
(obj as unknown) as UpdateSubscriptionPlanResponse,
);
} catch (error) {
const errorInfo = error as HttpError;
throw new RpcException({
code: errorInfo.statusCode,
message: JSON.stringify(error),
});
}
}
/**
* Delete subscription plan
* Test command : grpcurl -d '{"id":"513-A"}' -plaintext  -proto rpc/rpc.proto 127.0.0.1:5000 rpc.SubscriptionPlanService/Delete
* @param {SubscriptionPlanFilter} where
* @returns {Promise<DeleteSubscriptionPlanResponse>}
* @memberof SubscriptionPlanController
*/
@GrpcMethod('SubscriptionPlanService', 'Delete')
async delete(
where: SubscriptionPlanFilter,
): Promise<DeleteSubscriptionPlanResponse> {
try {
const id = where?.id;
const obj = await this.subscriptionPlanService.delete({ id });
return DeleteSubscriptionPlanResponse.create(
(obj as unknown) as DeleteSubscriptionPlanResponse,
);
} catch (error) {
const errorInfo = error as HttpError;
throw new RpcException({
code: errorInfo.statusCode,
message: JSON.stringify(error),
});
}
}
}

我还将订阅模块添加到了应用程序模块中。

我的应用程序模块.ts

import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import GraphQLJSON, { GraphQLJSONObject } from 'graphql-type-json';
import _ from 'lodash';
import { ConfigModule } from './config/config.module';
// import { servicesContainer } from './services/inversify.config';
import { ServicesModule } from './services/service.module';
// import { SubscriptionPlanService } from './services/SubscriptionPlan/subscription_plan.service';
import { HttpExceptionFilter } from './shared/exception-filter/http-exception.filter';
import { TimeoutInterceptor } from './shared/interceptor/timeout.interceptor';
import schemaDirectives from './shared/schema-directive/index';
import { SubscriptionPlanModule } from './subscription_plans/subscription_plan.module';
import { UserModule } from './users/user.module';
@Module({
imports: [
ConfigModule,
ServicesModule,
SubscriptionPlanModule,
UserModule,
GraphQLModule.forRootAsync({
useFactory: () => ({
schemaDirectives,
include: [],
typePaths: ['./**/**/*.graphql'],
installSubscriptionHandlers: true,
context: ({ req }) => ({ req }),
introspection: true,
// debug: configService.get<string>('app.nodeEnv') === 'development',
// engine: {
//   schemaTag: configService.get<string>('app.nodeEnv'),
//   apiKey: configService.get<string>('app.apolloEngineApiKey'),
// },
resolverValidationOptions: {
requireResolversForResolveType: false,
},
resolvers: {
JSON: GraphQLJSON,
JSONObject: GraphQLJSONObject,
},
formatError: (error) => {
try {
error.message = JSON.parse(error.message);
} catch (e) {
// Empty
}
return {
...error,
message: error.message,
code: _.get(error, 'extensions.exception.title', 'UNKNOWN'),
locations: error.locations,
path: error.path,
};
},
formatResponse: (response) => response,
}),
inject: [ConfigService],
}),
],
controllers: [],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: TimeoutInterceptor,
},
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
},
],
})
export class AppModule {
constructor() {
// Debug the Insert operation
// const s = servicesContainer.get<SubscriptionPlanService>(
//   SubscriptionPlanService,
// );
// void s.create({
//   name: 'Test',
//   invoice_duration: 'DAY',
//   invoice_period: 30,
//   price: 10,
//   code: '12312',
//   description: 'test',
//   trail_duration: 'DAY',
//   trail_period: 12,
// });
// void s.findAll();
// void s.delete({ id: '257-A' });
// void s.findOne({ id: '257-A' });
// void s.update({ name: 'Test Update name1' }, { id: '353-A' });
}
}

我觉得分享所有这些代码是不必要的,但如果有人需要任何信息,请在评论中告诉我。

即使你知道上面提到的问题可能是什么,也会有很大的帮助。

当服务器中的一切似乎都按预期工作时,我收到了相同的错误消息。原来我在错误的目录中调用grpurl。

根据参数-proto rpc/rpc.proto,您应该检查您是否在rpc的父目录中,然后再次尝试调用grpurl。

gRPCurl项目已经建议将错误消息更改为更好的错误消息。

更新:上面的错误消息问题似乎已经修复,如文中所述:

无法处理原型源文件。:无法分析给定的文件:打开<您在此处给定的proto路径和文件参数>:没有这样的文件或目录

最新更新