My file size is 2483385kb, the following code using Papa Parser does not help me:
this.readFile((output) => {
_this.sample = get(Papa.parse(output, {preview: 2, skipEmptyLines: true, chunkSize: 1024 * 1024 * 45}), "data");
_this.csv = get(Papa.parse(output, {skipEmptyLines: true, chunkSize: 1024 * 1024 * 45}), "data");
});
It cannot read the large csv file. Am I doing it wrongly?
You can try streaming.
/**
* Returns an async generator that yields the CSV file line-by-line.
*
* #param path {String}
* #param options {papa.ParseConfig}
*/
async function* readCsvStream(path, options) {
const csvStream = createReadStream(path);
const parseStream = papa.parse(papa.NODE_STREAM_INPUT, options);
csvStream.pipe(parseStream);
for await (const chunk of parseStream) {
yield chunk;
}
}
(async () => {
try {
const asyncIterator = readCsvStream(`${__dirname}/cad_fi.csv`, {
header: true,
dynamicTyping: true,
});
for await (const chunk of asyncIterator) {
// You can do anything with each row of the `.csv` file here.
// like saving it to a DB row by row
console.log(chunk);
}
} catch (error) {
console.error(error);
}
})();
Or, alternatively, you can pass a step callback to the parse function, which will be called on each line, thus avoiding loading the entire csv in memory.
/**
* Reads a CSV file.
*
* #param path {String}
* #param options {papa.ParseConfig}
*/
function readCsv(csvString, stepCallback, options) {
papa.parse(csvString, {
...options,
step: stepCallback,
});
}
(async () => {
// I read it from FS because it is NodeJs, but you can get the string by any means.
const csv = (await readFile(`${__dirname}/cad_fi.csv`)).toString();
const data = [];
const errors = [];
const stepCallback = (results, parser) => {
if (results?.errors?.length) {
errors.push(...results.errors);
}
data.push(results.data);
};
const papaparseOptions = {
header: true,
dynamicTyping: true,
};
try {
readCsv(
csv,
stepCallback,
papaparseOptions,
);
console.log(errors);
console.log(data.length);
} catch (error) {
console.error(error);
}
})();
I am trying to create a discord bot for the first time in my life so I would like to say that my code is far from being perfect and optimized ^^ '
I have a problem, TypeError: Cannot read properties of null (reading 'play').
The problem occurs when I try the "skip" command. Everything works fine but when I try the command I have absolutely nothing in my debugging console and only an error on discord returned by the bot.
Play command:
const { VoiceConnection } = require("discord.js");
const { Command, CommandoMessage } = require("discord.js-commando");
const ytdl = require('ytdl-core-discord');
const {UserNotInVoiceChannel } = require(`../../strings.json`);
module.exports = class PlayCommand extends Command {
constructor(client) {
super(client, {
name: `play`,
aliases: [`p`],
group: `music`,
memberName: `play`,
description: `Lit une video youtube`,
args: [
{
key: `query`,
prompt: `Quelle musique veux tu lire?`,
type: `string`
}
]
});
}
/**
*
* #param {CommandoMessage} message
* #param {String} query
*/
async run(message, { query }) {
const server = message.client.server;
if(!message.member.voice.channel){
return message.say(UserNotInVoiceChannel);
}
await message.member.voice.channel.join().then((connection) => {
if (server.currentVideo.url != "") {
server.queue.push({ title: "", url: query });
return message.say("Ajouté a la file d'attente")
}
server.currentVideo = { title: "", url: query };
this.runVideo(message, connection, query);
});
}
/**
*
* #param {*} message
* #param {VoiceConnection} connection
* #param {*} video
*/
async runVideo(message, connection, videoUrl) {
const server = message.client.server;
const dispatcher = connection.play(await ytdl(videoUrl, {filter: 'audioonly'}), { type: 'opus' });
server.queue.shift();
server.dispatcher = dispatcher;
server.connection = null
dispatcher.on('finish', () => {
if (server.queue[0]) {
server.currentVideo = server.queue[0];
return this.runVideo(message, connection, server.currentVideo.url);
}
});
return message.say("En train de jouer :notes:");
}
}
Skip command:
const { Command, CommandoMessage } = require("discord.js-commando");
const {UserNotInVoiceChannel, BotNotInVoiceChannel } = require(`../../strings.json`);
module.exports = class skipCommand extends Command {
constructor(client) {
super(client, {
name: `skip`,
group: `music`,
memberName: `skip`,
description: `Skip la video.`
});
}
/**
*
* #param {CommandoMessage} message
* #param {String} query
*/
async run(message) {
const voiceChannel = message.member.voice.channel;
const server = message.client.server;
if(!voiceChannel){
return message.say(UserNotInVoiceChannel)
}
if (!message.client.voice.connections.first()) {
return message.say(BotNotInVoiceChannel);
}
server.queue.shift();
if (!server.queue[0]) {
server.currentVideo = {url: "", title: "Rien pour le moment"}
}
server.currentVideo = server.queue[0];
server.connection.play(await ytdl(server.currentVideo.url, {filter: 'audioonly'}), { type: 'opus' } );
return message.say(":fast_foward: Ignoré :thumbsup:");
}
}
The error says that it cannot read properties of null (reading 'play') in your skip command. It means that server.connection is null.
If you check your play command, you can see that inside runVideo you set server.connection = null.
Did you mean to assign the connection passed to runVideo?
async runVideo(message, connection, videoUrl) {
const server = message.client.server;
const dispatcher = connection.play(
await ytdl(videoUrl, { filter: 'audioonly' }),
{ type: 'opus' },
);
server.queue.shift();
server.dispatcher = dispatcher;
server.connection = connection;
dispatcher.on('finish', () => {
if (server.queue[0]) {
server.currentVideo = server.queue[0];
return this.runVideo(message, connection, server.currentVideo.url);
}
});
return message.say('En train de jouer :notes:');
}
I'm trying to implement a password validation system to accept a user's "update password" request.
I'm using Strapi as my backend and Next.js as my frontend.
Strapi says it uses "bcrypt with autogenerated salt and hash" (mentioned here)
so the stored password is encrypted.
I use MongoDB for my database.
The user is registered, I use it for all my tests so I know the password is correct.
Question: What am I doing wrong ?
I am very new to this.
Thank you.
Comparison code in my controller file :
I did this but it always return false (backend):
const comparePass = await bcrypt.compare(oldPassword, user.password);
if(comparePass){
ctx.throw(200, 'valid password !')
}else{
ctx.throw(400, 'wrong password !')
}
When I debbug I can see in my console that:
oldPassword = 'maddie'
user.password ='$2a$10$tEXnOI.OASIeL0BsG2Go/ecHjXn38xNnM9HVHJlPnBFpqSRe6Yyf6'
which is correct
Hashing code- In my backend, this code below used to hash the password when the user register:
hashPassword(user = {}) {
return new Promise(resolve => {
if (!user.password || this.isHashed(user.password)) {
resolve(null);
} else {
bcrypt.hash(`${user.password}`, 10, (err, hash) => {
resolve(hash);
});
}
});
},
Complete code in my User.js service including the hashing code:
'use strict';
/**
* User.js service
*
* #description: A set of functions similar to controller's actions to avoid code duplication.
*/
const bcrypt = require('bcryptjs');
const crypto = require('crypto');
const { sanitizeEntity, getAbsoluteServerUrl } = require('strapi-utils');
module.exports = {
/**
* Promise to count users
*
* #return {Promise}
*/
count(params) {
return strapi.query('user', 'users-permissions').count(params);
},
/**
* Promise to search count users
*
* #return {Promise}
*/
countSearch(params) {
return strapi.query('user', 'users-permissions').countSearch(params);
},
/**
* Promise to add a/an user.
* #return {Promise}
*/
async add(values) {
if (values.password) {
values.password = await strapi.plugins['users-permissions'].services.user.hashPassword(
values
);
}
return strapi.query('user', 'users-permissions').create(values);
},
/**
* Promise to edit a/an user.
* #return {Promise}
*/
async edit(params, values) {
if (values.password) {
values.password = await strapi.plugins['users-permissions'].services.user.hashPassword(
values
);
}
return strapi.query('user', 'users-permissions').update(params, values);
},
/**
* Promise to fetch a/an user.
* #return {Promise}
*/
fetch(params, populate) {
return strapi.query('user', 'users-permissions').findOne(params, populate);
},
/**
* Promise to fetch authenticated user.
* #return {Promise}
*/
fetchAuthenticatedUser(id) {
return strapi.query('user', 'users-permissions').findOne({ id }, ['role']);
},
/**
* Promise to fetch all users.
* #return {Promise}
*/
fetchAll(params, populate) {
return strapi.query('user', 'users-permissions').find(params, populate);
},
hashPassword(user = {}) {
return new Promise(resolve => {
if (!user.password || this.isHashed(user.password)) {
resolve(null);
} else {
bcrypt.hash(`${user.password}`, 10, (err, hash) => {
resolve(hash);
});
}
});
},
isHashed(password) {
if (typeof password !== 'string' || !password) {
return false;
}
return password.split('$').length === 4;
},
/**
* Promise to remove a/an user.
* #return {Promise}
*/
async remove(params) {
return strapi.query('user', 'users-permissions').delete(params);
},
async removeAll(params) {
return strapi.query('user', 'users-permissions').delete(params);
},
validatePassword(password, hash) {
return bcrypt.compare(password, hash);
},
I'm working on a nest.js microservices project. The controllers and services are defined and the back-end runs without errors. I'm trying to create a resource(subscriptionPlan in this example) using
grpCurl, like this:
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
when I run this command I get an error message: Failed to process proto source files.: could not parse given files: %!v(PANIC=Error method: runtime error: invalid memory address or nil pointer dereference).
I feel there isn't a problem in the back-end/services code , it's something with the project set-up maybe I'm missing a library on command-line tools. I checked x-code dev tools are installed and all the module dependencies are also installed.
here is my : 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'));
}
}
Here is my 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),
});
}
}
}
I have also added the subscription module to app modules.
my 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' });
}
}
I feel like sharing all these code were un-necessary but if anyone needs any kind of information do let me know in the comments.
Even if you a clue to what might be raising the issue mentioned above would be of great help.
I got the same error message while everything in the server seemed to work as expected. It turned out I was calling grpcurl in the wrong directory.
Based on the argument -proto rpc/rpc.proto, you should check that you are in the parent directory of rpc and try calling grpcurl again.
The gRPCurl project already has a suggestion to change the error message to a better one.
UPDATE: The above bad error message issue seems to be fixed as mentioned in it:
Failed to process proto source files.: could not parse given files: open <your given proto path and file argument here>: no such file or directory