How to use RTK Query with ErrorBoundary - redux-toolkit

Are there some examples of use with ErrorBoundary?
This is what i can think of:
const { isError: isGetAError, error: getAError } = useGetAQuery()
if (isGetAError) {
throw getAError
}
const { isError: isGetBError, error: getBError } = useGetBQuery()
if (isGetBError) {
throw getBError
}

That would probably be the way to do it, or you create your own throwingHooks module with your own way of writing hooks - these are pluggable modules.
Here is the code to the /query/react module: https://github.com/reduxjs/redux-toolkit/tree/master/packages/toolkit/src/query/react

Related

I can't succeed to correctly handle exceptions in NestJs

I'm trying to learn NestJs by creating a CRUD API.
I've created my controller, module, service etc...
And created a get users/id endpoint. Everything worked fine, and I decided to add some security.
I want to check if the id is not null and is a string. If not, I want to throw an exception (bad request) + console.log a message.
I also want to check if when I look for a user with a good if, the user exists. if not, throw a not found exception.
Here is my service:
async findOne(id: string): Promise<IUser | null> {
if (id === null || typeof id !== 'string') {
throw new BadRequestException('Id must be a string');
}
const user = await this.userModel.findById(id).exec();
if (user === null) {
throw new NotFoundException('No user found for this id');
}
return user;
}
and controller:
#Get(':id')
async find(#Param('id') id: string) {
try {
return await this.userService.findOne(id);
} catch (error) {
if (error instanceof BadRequestException) {
throw new HttpException(
{
status: HttpStatus.FORBIDDEN,
error: 'This is a custom message',
},
HttpStatus.FORBIDDEN,
{
cause: error,
},
);
} else if (error instanceof NotFoundException) {
throw new HttpException(
{
status: HttpStatus.NOT_FOUND,
error: 'This is a custom not found message',
},
HttpStatus.NOT_FOUND,
{
cause: error,
},
);
}
}
}
The problem is when I try a get request with .../users/1111 ,I got a 200 response. And when I try with a good id (a string) but with no user linked, I also get a 200 response.
I don't understand why.. Can you help me please ?
I also want to log the message.
And have you any advices ? Is the right way (standard + elegant) to do ?
Thanks guys ;)
In your code you are checking id to be of a type string and not null. Technically any param is a string, so even 1111 becomes "1111". You can verify that by logging it like so console.log({ id }) (expected result: { id: "1111" }).
For the validation I would suggest to follow the documentation on validation pipes: NestJS documentation.
TLDR;
The following code will add a global pipe to validate payloads
app.module.ts (copied from NestJS | Pipes)
import { Module } from '#nestjs/common';
import { APP_PIPE } from '#nestjs/core';
#Module({
providers: [
{
provide: APP_PIPE,
useClass: ValidationPipe,
},
],
})
export class AppModule {}
To make it work you will need to have class-validator and class-transformer installed, so run:
npm i --save class-validator class-transformer
Then declare a class that will serve as a blueprint of a DTO (Data Transfer Object), like so:
import { IsString, IsNotEmpty } from 'class-validator';
export class IdDto {
#IsNotEmpty()
#IsString()
id: string;
}
Then in your controller use the IdDto:
#Get(':id')
async find(#Param() { id }: IdDto) {
...
This already should be enough to have a basic validation. Moreover, this will convert the payload to a format that you expect (or fail and throw validation error). It is done via plainToClass method exposed from class-transformer. So there won't be any surprises with JavaScript type coercion like "1" + 1 = "11".
If you need to format your exceptions (or enrich them with additional data) you can use exception filters. There is a nice documentation about it in the official documentation.
Hope that helps!

How to handle non explicit errors inside sails.js helpers?

I am trying to figure out how the Error handling in Sails.js works. Unfortunatley the code examples in the docs do not cover this use case.
The problem is I keep getting this error:
UsageError: `.intercept()` handler returned `undefined`, but this should never happen.
Regardless, here is a summary of the original underlying error:
Now all I am trying to do is call a helper and if it fails, then I want to catch the error (any), log it and run some code. If I wouldn't be using Sails but normal promises I would have handled it like this:
await helper().catch((err) => { // run some code }
In Sails I should be able to use .intercept() instead of .catch()
My code looks like this:
// ExportController.js
const csv = await sails.helpers.files.convertToCsv(data)
.intercept((err) => {
sails.log.error(err)
req.addFlash('error_messages', 'Error parsing data to csv!')
return res.redirect(`/`);
})
// convert-to-csv.js
if (!Array.isArray(inputs.data)) {
throw new Error('invalid inputs.data type: ' + typeof inputs.data)
};
Now how can I avoid getting this error?
The code examples show only cases where errors that are explicitly added to the exits object are handled, but not for general error handling.
In the docs it says that if the filter argument is
not provided, ALL errors will be intercepted.
Or is that only true for db queries? Because the .intercept() doc section is in that subcategory.
You could use “throw ‘errorCode’;” for example:
Set the exits:
exits {
errorWithCsvFile: {
responseType: 'badRequest'
}
}
const csv = await sails.helpers.files.convertToCsv(data)
.intercept(‘somethingWrongCode’, ‘errorWithCsvFile’)
... // Other handles
.intercept(err => new Error(err))
Alternative:
try {
...
const csv = await sails.helpers.files.convertToCsv(data)
.intercept((err) => {
sails.log.error(err)
req.addFlash('error_messages', 'Error parsing data to csv!')
throw 'badRequest';
})
...
} catch (err) {
sails.log.err(err);
return res.redirect(`/`);
}

Firestore check if document already exist using try await

Trying to check if doc already exist before saving it but I wanted to use try, await here is my example:
try {
const payload = await db.collection('cities').doc('LA').get()
if (!payload.exists) {
try {
const payload = await db.collection('cities').doc('LA').set(data)
if (payload.exists()) {
response.send(payload);
}
} catch (error) {
response.send(error);
}
} else {
response.send({error: "document exists!"});
}
} catch (error) {
response.send(error);
}
Just wanted to check if it's the best way to do it?
try/catch is not functionally any different than then()/catch(). It's just a different syntax that simplifies dealing with promises.
I don't know what your definition of "best way" is, but if it works OK for you with a minimal amount of code, I'm sure it's OK.

mirth connect - post db query executes only after checking pre query send status -Error/sent? Advice required

Basically, I am new to mirth connect. Please give me advice on this.
When I use something like this on Run Post-Process script:
try {
dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.jdbc.Driver','jdbc:mysql://localhost:3306/mirth','XYZ','XYZ');
a =$('his_user_id');
responseStatus=Response.getStatus();
loger.info(responseStatus);
if(responseStatus == SENT) {
var result = dbConn.executeUpdate("UPDATE his_user SET status =0 where id"+a);
return result;
}
}
finally {
if (dbConn) {
dbConn.close();
}
}
I am getting the below error:
SourceSOURCE CODE:
53: var dbConn;54: 55: try {56:
dbConn = DatabaseConnectionFactory.createDatabaseConnection
('com.mysql.jdbc.Driver','jdbc:mysql://localhost:3306/mirth',
'root','root');57: a =$('his_user_id');58:
responseStatus=Response.getStatus();59:
loger.info(responseStatus);60: if(responseStatus == SENT)61:
{62: LINE NUMBER: 58DETAILS:
Java class "com.mirth.connect.userutil.Response" has
no public instance field or method named "getStatus". at
0462ff2d-8942-4898-9afb-802bfe68a63d:58
(doScript) at 0462ff2d-8942-4898-9afb-802bfe68a63d:74
This is my Pre process script in db writer
var dbConn;
try {
dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.jdbc.Driver','jdbc:mysql://localhost:3306/mirth','root','root');
var result = dbConn.executeCachedQuery("SELECT his_user.Id AS his_user_Id, his_user.His_username AS his_user_His_username, his_user.His_useraddress AS his_user_His_useraddress, his_user.status AS his_user_status FROM his_user where his_user.status='1'");
return result;
}
finally {
if (dbConn) {
dbConn.close();
}
}
Change your dbConn to use this instead and it should work...
importPackage(java.sql);
var dbConn= java.sql.DriverManager.getConnection('jdbc:jtds:sqlserver://localhost:1433/dbname','user','pass');
If you do not feel like changing your dbConn, you may be able to circumvent that by replacing "dbConn.prepareStatement" with "dbConn.getConnection().prepareStatement". If that doesn't work, you may also need to include "importPackage(java.sql);" at the beginning of your transformer code.

Not able to encrypt a string with a public key in Protractor

I am trying call the encrypt function mentioned below:
var encryptor = require("./jsencrypt.js");
this.encrypt = function () {
var key="LxVtiqZV6g2D493gDBfG0BfV6sAhteG6hOCAu48qO00Z99OpiaIG5vZxVtiqZV8C7bpwIDAQAB";
encryptor = new JSEncrypt();
encryptor.setPublicKey(key);
var newString = encryptor.encrypt('Password');
console.log("Encrypted password =",newString);
}
Initially I was getting Reference Error for undefined JSEncrypt.
So I downoaded jsencrypt.js file and added var encryptor = require("./jsencrypt.js");at the begining. Now I am getting following error:
Message:
ReferenceError: navigator is not defined
Stacktrace:
ReferenceError: navigator is not defined
at e:\Praveen Data\Projects\ECP\CentralRegistryUI\TestScripts\Utils\jsencrypt.js:73:13
at Object.<anonymous> (e:\Praveen Data\Projects\ECP\CentralRegistryUI\TestScripts\Utils\jsencrypt.js:4342:3)
at require (module.js:385:17)
Tried using windows.navigator in jsencrypt.js, but didn't work.
Protractor tests are not run in browser environment but in node.js, because of that navigator object is not available there. JSEncrypt relies on it to work on the client side across different browsers and versions.
It's referenced in many places in the JSEncrypt code so my best bet would be to either switch to a server side encryption library that would work for you or if not possible mock a global navigator json object with all expected properties/methods as if it was a Chrome browser - node.js runs on chrome's js engine so should work fine.
One of my colleague helped me with the solution.
So here I have a function for encryption:
this.initializeEncryptedPassword = () => {
//console.log("before calling encrypt... ");
browser.executeScript(() => {
//console.log("Starting to return encryptor...");
return window.loginEncryptor.encrypt(window.loginPassword);
}).then((encryptedPassword) => {
this.encryptedPassword = encryptedPassword;
});
//console.log("after calling encrypt...");
}
This function is being called by:
export default class Encryptor {
constructor($window, $http) {
'ngInject';
this.encryptor = new $window.JSEncrypt();
//Need to use HTTP here instead of resource since the resource does not return plain text.
//Getting Public Key by hitting a rest uri.
$http({method: "GET", url: "/xyz/authenticate"}).success((item) => {
this.encryptor.setPublicKey(item);
//set the current encryptor on the window so that testing can use it
$window.loginEncryptor = this.encryptor;
});
}
encryptPassword(credentials) {
credentials.password = this.encryptor.encrypt(credentials.password);
}
}
Hope this help others.
before require('jsencrypt') you can write first:
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;
global.window = window;
global.document = window.document;
global.navigator ={userAgent: 'node.js'};
const { JSEncrypt } = require('jsencrypt')
You can mock by doing the following:
global.navigator = { appName: 'protractor' };
global.window = {};
const JSEncrypt = require('JSEncrypt').default;