微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决错误方法:运行时错误:无效的内存地址或nil指针取消引用

我正在研究nest.js微服务项目。定义了控制器和服务,后端运行无误。我正在尝试使用创建资源(在此示例中为subscriptionPlan) grpCurl,像这样:

 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,});
      // 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,});
      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,Partial<SubscriptionPlanFilter>
          >(new SubscriptionPlans(),recordSkip);
        } else if (!_.isNil(id)) {
          // Load All SubscriptionPlan with id with default pagination
          [edges,recordSkip);
        }
      } else {
        // Load All SubscriptionPlan with default pagination
        [edges,count] = await this.dbService.findAll<
          SubscriptionPlan,Partial<SubscriptionPlanFilter>
        >(new SubscriptionPlans(),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,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',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,});
    }
  }

  /**
   * Create subscription plan
   * Test command : grpcurl -d '{
      "name": "Test GRPC","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,});
    }
  }

  /**
   * 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,});
    }
  }
}

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

我的app.module.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' });
  }
}

我觉得不必共享所有这些代码,但是如果有人需要任何信息,请在评论中让我知道。

即使您对可能引起上述问题的线索有很大的帮助。

解决方法

当服务器中的所有内容似乎都按预期运行时,我收到了相同的错误消息。原来我在错误的目录中调用了grpcurl。

基于参数-proto rpc/rpc.proto,应检查自己是否位于rpc的父目录中,然后尝试再次调用grpcurl。

gRPCurl项目已经有了一个suggestion to change the error message更好的项目。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。