R
Railway16mo ago
xbisa

Error: read ECONNRESET at TCP.onStreamRead

Now and then I get the exception below. I have to make the same request 3 times before I get a response from my NestJS API app. [Nest] 32 - 08/03/2023, 8:08:30 AM ERROR [ExceptionsHandler] select * from "municipalities" order by "name" asc - read ECONNRESET Error: read ECONNRESET at TCP.onStreamRead (node:internal/stream_base_commons:217:20) Connection Error: Connection ended unexpectedly The above log is from NestJS API log. Can someone point me in the right direction?
35 Replies
Percy
Percy16mo ago
Project ID: 79b7240f-dddf-498a-a330-e4ecb87b23f3
xbisa
xbisaOP16mo ago
79b7240f-dddf-498a-a330-e4ecb87b23f3
Brody
Brody16mo ago
what package are you using for the database?
xbisa
xbisaOP16mo ago
I'm using knex and nestjs-knex.
Brody
Brody16mo ago
can I see your connection code?
xbisa
xbisaOP16mo ago
sure
import { Injectable } from '@nestjs/common';
import { InjectKnex, Knex } from 'nestjs-knex';
import { Municipality } from '@xbisa#1020/appability';
import { permittedFieldsOf } from '@casl/ability/extra';
import { hasKeys } from '../service-helpers';
import { pick } from 'lodash';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class MunicipalitiesService {
constructor(@InjectKnex() private readonly knex: Knex) {}

public async findAll(request: any): Promise<{ data: Array<Municipality> }> {
const dbMunicipalities = await this.knex
.select('*')
.from('municipalities')
.orderBy('name');

const municipalities: Municipality[] = plainToInstance(
Municipality,
dbMunicipalities,
);

const data: Municipality[] = municipalities
.map((municipality: Municipality) => {
const fields: string[] = permittedFieldsOf(
request.ability,
'read',
municipality,
{
fieldsFrom: (rule) => {
return rule.fields || [];
},
},
);
return pick(municipality, fields) as Municipality;
})
.filter((municipality: Municipality) => {
return hasKeys(municipality);
});

return { data };
}
}
import { Injectable } from '@nestjs/common';
import { InjectKnex, Knex } from 'nestjs-knex';
import { Municipality } from '@xbisa#1020/appability';
import { permittedFieldsOf } from '@casl/ability/extra';
import { hasKeys } from '../service-helpers';
import { pick } from 'lodash';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class MunicipalitiesService {
constructor(@InjectKnex() private readonly knex: Knex) {}

public async findAll(request: any): Promise<{ data: Array<Municipality> }> {
const dbMunicipalities = await this.knex
.select('*')
.from('municipalities')
.orderBy('name');

const municipalities: Municipality[] = plainToInstance(
Municipality,
dbMunicipalities,
);

const data: Municipality[] = municipalities
.map((municipality: Municipality) => {
const fields: string[] = permittedFieldsOf(
request.ability,
'read',
municipality,
{
fieldsFrom: (rule) => {
return rule.fields || [];
},
},
);
return pick(municipality, fields) as Municipality;
})
.filter((municipality: Municipality) => {
return hasKeys(municipality);
});

return { data };
}
}
It's not a problem relating to this endpoint
Brody
Brody16mo ago
do me a favour and enclose that code with triple backticks?
xbisa
xbisaOP16mo ago
just a second
Brody
Brody16mo ago
but I'd like to see the code that connects to the database, that doesn't have anything to do with connecting to the database
xbisa
xbisaOP16mo ago
Oh I see
Brody
Brody16mo ago
and remember, triple backticks please
xbisa
xbisaOP16mo ago
I'm doing that in my app.module.ts
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
}),
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
},
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
// eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/no-unused-vars
configure(consumer: MiddlewareConsumer): any {}
}
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
}),
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
},
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
// eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/no-unused-vars
configure(consumer: MiddlewareConsumer): any {}
}
Brody
Brody16mo ago
show me the configuration().database code please
xbisa
xbisaOP16mo ago
export default () => ({
port: +process.env.API_PORT,
database: {
host: process.env.DATABASE_HOST,
port: +process.env.DATABASE_PORT,
database: process.env.DATABASE,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
},
});
export default () => ({
port: +process.env.API_PORT,
database: {
host: process.env.DATABASE_HOST,
port: +process.env.DATABASE_PORT,
database: process.env.DATABASE,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
},
});
this is my configuration.ts
Brody
Brody16mo ago
I assume this is for postgres
xbisa
xbisaOP16mo ago
yes
Brody
Brody16mo ago
in the config object can you please add this
pool: { min: 0, max: 10 }
pool: { min: 0, max: 10 }
and show me the code again after that change?
xbisa
xbisaOP16mo ago
2 sec
export default () => ({
port: +process.env.API_PORT,
database: {
host: process.env.DATABASE_HOST,
port: +process.env.DATABASE_PORT,
database: process.env.DATABASE,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
pool: { min: 0, max: 10 },
},
});
export default () => ({
port: +process.env.API_PORT,
database: {
host: process.env.DATABASE_HOST,
port: +process.env.DATABASE_PORT,
database: process.env.DATABASE,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
pool: { min: 0, max: 10 },
},
});
Like this?
Brody
Brody16mo ago
no, not quite in the config object can you please add this
pool: { min: 0, max: 10 }
pool: { min: 0, max: 10 }
xbisa
xbisaOP16mo ago
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
pool: { min: 0, max: 10 },
},
},
}),
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
pool: { min: 0, max: 10 },
},
},
}),
is this better?
Brody
Brody16mo ago
no, you aren't putting it where I'm saying to the pool object goes in the config object
xbisa
xbisaOP16mo ago
yes, I see now from the doc
Brody
Brody16mo ago
alright show code please
xbisa
xbisaOP16mo ago
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
},
pool: { min: 0, max: 10 },
},
})
KnexModule.forRoot({
config: {
client: 'pg',
connection: {
...configuration().database,
},
pool: { min: 0, max: 10 },
},
})
Brody
Brody16mo ago
there we go pool is now in config
xbisa
xbisaOP16mo ago
what is the significance of pool? Yes
Brody
Brody16mo ago
one sec, let me find that info for you now this is for strapi, but the exact same information applies to you since you are using knex too, read the caution blurb https://docs.strapi.io/dev-docs/configurations/database#database-pooling-options
xbisa
xbisaOP16mo ago
are services at Railway hosted by docker containers?
Brody
Brody16mo ago
yes they are
xbisa
xbisaOP16mo ago
Then I understand the issue Thanks for helping resolve my issue
Brody
Brody16mo ago
alrighty then, let me know if you continue to see this issue after you deploy this change!
xbisa
xbisaOP16mo ago
Okay, I will deploy and see if it solves the problem, hopefully it will
Brody
Brody16mo ago
awesome
xbisa
xbisaOP16mo ago
Hello Brody. Everything looks good since deployment of pool object. Thanks again for great support, it's a big incentive for us to stay on Railway platform.
Brody
Brody16mo ago
I'm happy to hear that, I'm glad I could help you 🙂
Want results from more Discord servers?
Add your server