NestJS Prisma: start application even if prisma can't connect to database - javascript

I'm trying to prevent prisma from from shutting my app down even if it fails to connect to the database, so that my health-check endpoint can still be reached. The error I get is this:
throw new PrismaClientInitializationError(error2.message, this.config.clientVersion, error2.error_code);
^
Error: Can't reach database server at `postgres`:`5432`
Please make sure your database server is running at `postgres`:`5432`.
at startFn (/home/my_name/my_folder/my-service/node_modules/#prisma/client/runtime/index.js:27186:17)
at Proxy.onModuleInit (/home/my_name/my_folder/my-service/src/services/prisma.ts:12:5)
which makes sense, because my database is shut off. But this crashes my nest application.
The prisma docs say that the PrismaClientInitializationError is returned whenprisma.$connect runs, or if a query is run.
The obvious solution to me was to wrap this.$connect with a try catch to prevent it from crashing and burning. So here is my attempt in my PrismaService - the file that the error above is complaining about my-service/src/services/prisma:
import { INestApplication, Injectable, OnModuleInit } from '#nestjs/common';
import { PrismaClient, Prisma } from '#prisma/client';
#Injectable()
export class PrismaService
extends PrismaClient<Prisma.PrismaClientOptions, 'query' | 'error'>
implements OnModuleInit
{
constructor() {
try {
super();
} catch (e) {
console.log(e);
}
}
async onModuleInit() {
this.$on('error', (event) => {
console.log(event.target);
});
try {
await this.$connect();
} catch (e) {
console.log(e);
}
}
async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit', async () => {
await app.close();
});
}
}
It's littered with console logs, and none of them log anything to the console. In fact, I found that even if I delete this.$connect if my database is up and running then prisma still connects to the database. If my database is not running I still get the same error message as above.
My question is, where do I need to put a try catch in order to prevent prisma from breaking my app?
And to satisfy my curiosity, why is the prisma client seemingly initializing itself even if I don't run this.$connect

This issue has seemingly resolved itself. and my error handling now works. I'm suspecting that because I was using docker compose with mounted volumes some sort of caching was getting in the way and not registering that I had put a try/catch there

Related

expo app not fetching updates from publish

For some reason, I need to close and reopen the app multiple times and even clear my cache before my expo app updates.
After seeing this I went through the documentation for expo updates and I put this code in my App.js but I don't understand how can I force the expo app to update as soon as one is available
async componentDidMount() {
try {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
await Updates.fetchUpdateAsync();
// ... notify user of update ...
await Updates.reloadAsync();
}
} catch (e) {
// handle or log error
console.log(`update his an error ${e}`)
}

How to run and read bluetoothctl commands outputs from NodeJS?

I want to periodically run commands to bluetoothctl via NodeJS, and be able to read the output of those commands.
For example I'd want to run the scan on, and get the output. As well as running devices and read the list. It's not matter that is a string, I can parse it, but I need to be able to interact with the bluetoothctl program.
The problem is that when you type in the terminal the command bluetoothctl it brings you in a "manager" like view, where I guess Node cannot read data from? Am I wrong?
I'm kinda lost, and I couldn't find anything useful. I've found some NodeJS bluetoothctl wrappers, but they're all old and requires deprecated versions of node..
Edit
Here's the code that I have so far. But the problem is that I don't get the expected output from the commands that I run, but instead I get the name of the command that I've called...
import * as cp from 'child_process';
async function sleep(ms) {
await new Promise(r => setTimeout(() => r(), ms));
return;
}
function log(m: string) {
console.log(`[${ShellyBluetoothScanner.name}] ${m}`);
}
export class ShellyBluetoothScanner {
bluetoothctl: cp.ChildProcessWithoutNullStreams;
constructor() {
this.setup();
}
async run() {
log('Running scan and devices list in 2s...');
await sleep(2000);
log('Enabling bluetooth');
this.bluetoothctl.stdin.write('power on');
await sleep(2000);
log('Claering devices');
this.bluetoothctl.stdin.write('remove *');
log('Scan devices for 3s');
this.bluetoothctl.stdin.write('scan on');
await sleep(3000);
log('Print devices');
this.bluetoothctl.stdin.write('devices');
}
private setup() {
log('INFO: Setting up bluetooth');
this.bluetoothctl = cp.spawn('bluetoothctl');
this.bluetoothctl.stdout.on('data', m => console.log('STDOUT Data - ', m.toString()));
this.bluetoothctl.stdout.on('error', error => console.log('STDOUT Error - ', error.message));
log('INFO: Bluetooth setup completed');
}
}
const SBTS = new ShellyBluetoothScanner();
SBTS.run();
I don't believe bluetoothctl was ever intended to be run in this way. It certainly has no documented API and I have seen the commands subtly change in the tool over time which will break your script.
A better way to achieve this is to use the D-Bus API that is documented and intended for this use.
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/gatt-api.txt
There are bindings available at: https://www.npmjs.com/package/dbus
I am sure there are also libraries that maybe helpful. Maybe https://www.npmjs.com/package/node-ble

Correct way to use async function inside a for-loop

Recently, I got some error when running the E2E tests and the only change I made is adding the checkColumns logic in the original test code as following:
it('check search and sort', async () => {
await checkLoadingAndResult();
await checkColumns(table, ...columns); //newly added
await checkTableSorting();
});
The logic of checkColumns is like:
export async function checkColumns(table: Table, ...columns: string[]) {
for (const col of columns) {
expect(await table.isColumnDisplayed(col)).toBeTruthy(`${col} is not displayed`)
}
}
The error message is like:
Error: ECONNREFUSED connect ECONNREFUSED 127.0.0.1:59536
I think maybe there's something wrong in the checkColumns function and I don't know whether it's a correct way to call async methods inside a for-loop. And I guess this for-loop is the cause of the error.
This error message is not generated by your usage of async / await.
It is most likely displayed because the HTTP request sent failed due to a connection error, I had the issue on another framework and it was due to the webdriver that was not running.

How to connect to MongoDb Atlas from firebase cloud functions

I'm trying to follow this answer to connect to a mongodb atlas db from cloud functions.
I use this code from the answer above:
import { MongoClient } from 'mongodb'
const uri = 'mongodb://<USER>:<PASSWORD>#foo-shard-00-00-xxx.gcp.mongodb.net:27017,foo-shard-00-01-xxx.gcp.mongodb.net:27017,foo-shard-00-02-xxx.gcp.mongodb.net:27017/test?ssl=true&replicaSet=FOO-shard-0&authSource=admin&retryWrites=true'
let client
export default async () => {
if (client && client.isConnected()) {
console.log('DB CLIENT ALREADY CONNECTED')
} else try {
client = await MongoClient.connect(uri, { useNewUrlParser: true })
console.log('DB CLIENT RECONNECTED')
}
catch (e) {
throw e
}
return client
}
And then I have a function like this:
export const myFunction = functions.region('europe-west1').https.onRequest((request, response) => {
console.log(client.isConnected());
});
When I run firebase serve locally, I don't see 'DB CLIENT ALREADY CONNECTED' or 'DB CLIENT RECONNECTED' which means that anonymous function didn't get called. And when I try to access the client variable inside myFunction I get an error.
I'm learning Node at the moment so this might be a simple question. Thanks,
If you have some code to run in Cloud Functions, you need to invoke it. It's not possible to simply declare or export some function and expect it to run without calling it. If you want something to run at the global scope of your code, either don't wrap it in a function, or call the function at the global scope.

Typical file structure in Reactjs application: grouping API calls in api.js

Just wanted to know how to group all of my API calls altogether in an api.js file, in my React App (just some pseudocode would work). I have read an interesting article that introduces that idea, and I feel curious because that file structure really fits my needs. How would it be?
Moreover, the author states in a comment:
I usually just put all of my API calls into that file - they're
usually small one-or-two-line functions that call out to axios, and I
just export them.
export function login(username, password) { ... } export function
getFolders() { ... } etc.
But I feel it lacks some details to reproduce it. I am new to Javascript and React. Thanks.
Say you are using axios for http calls, I guess it would be smth like this:
api.js:
import axios from 'axios';
import { resolve } from './resolve.js';
export async function login(user, pass) {
return await resolve(axios.post('http://some-api.com/auth', { user, pass }).then(res => res.data));
}
export async function getUser(id) {
return await resolve(axios.get(`http://some-api.com/users/${id}`).then(res => res.data));
}
// and so on....
And as he said on the post, If your files starts to get too big, you can create a src/api/ and create separate files like src/api/auth.js, src/api/users.js, etc..
To resolve the promises I like to use the new async/await syntax and wrap it in a little module resolver.js:
export function async resolve(promise) {
const resolved = {
data: null,
error: null
};
try {
resolved.data = await promise;
} catch(e) {
resolved.error = e;
}
return resolved;
}
And your component smth like:
// ...
componentDidMount() {
this.getUser();
}
async getUser() {
const user = await api.getUser(this.props.id);
if(user.error)
this.setState({ error: user.error });
else
this.setState({ user: user.data });
}
Again, this is something I like to do, I think the code looks clearer, keeping a synchronous structure. But I guess it's perfectly fine to resolve your promises with .then() and .catch() also.
I hope that helped!
It depends on how much API functions a project has.
I usually stick with project structure called "grouping by file type" mentioned in React official website and keep API related files in a separate directory where every file has an API functionality dedicated to a specific entity.
However, for small projects, it makes sense to keep all API functionality in one file.

Categories