I'm trying to get my head around Koa and I am making small progress. At the moment I think I understand this code
import Koa from 'koa';
import router from './router';
const app = new Koa();
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.body = { message: err.message };
ctx.status = err.status || 500;
}
});
app.use(router.routes());
app.listen(3000);
export default app;
Instead of having a callback to handle the error, we go upstream to that catch. But I would like to make the above error execute.
How can I simulate an error
If you have an unhandled error in your upstream code, THEN this error here would fire.
To simulate an error do :
throw new Error('error message')
Related
I'm creating an application that is using Nestjs with websockets, but now I need to add rate limit on the sockets, but analyzing the documentation documentation link and implementing what it says in it, when I use #UseGuards(MyGuard) an error occurs in the application.
My Guard:
#Injectable()
export class NewThrottlerGuard extends ThrottlerGuard {
protected async handleRequest(
context: ExecutionContext,
limit: number,
ttl: number,
): Promise<boolean> {
console.log('Request');
const client = context.switchToWs().getClient();
const ip = client.conn.remoteAddress;
const key = this.generateKey(context, ip);
const ttls = await this.storageService.getRecord(key);
if (ttls.length >= limit) {
throw new ThrottlerException();
}
await this.storageService.addRecord(key, ttl);
return true;
}
}
Websocket:
#UseGuards(NewThrottlerGuard)
#SubscribeMessage('sendMessage')
sendMessage(
#ConnectedSocket() client: Socket,
#MessageBody() message: string,
) {
client.rooms.forEach((room) => {
if (room !== client.id) {
client.broadcast.to(room).emit('message', message);
}
});
}
Error in console:
/node_modules/#nestjs/common/utils/validate-each.util.js:22
throw new InvalidDecoratorItemException(decorator, item, context.name);
^
Error: Invalid guard passed to #UseGuards() decorator (ChatGateway).
at validateEach
The file in: #nestjs/common/utils/validate-each.util.js:22
function validateEach(context, arr, predicate, decorator, item) {
if (!context || !context.name) {
return true;
}
console.log(context, arr)
const errors = arr.some(str => !predicate(str));
if (errors) {
throw new InvalidDecoratorItemException(decorator, item, context.name);
}
return true;
}
i put some console.log then in the terminal it show:
[Function: ChatGateway] [ undefined ]
In Github Throttler documentation they say: You cannot bind the guard with APP_GUARD or app.useGlobalGuards() due to how Nest binds global guards.
So, im using #UseGuards()
The guard itself was written correctly, but it was put in a location that importing it made a circular reference between files, so when #UseGuards() was used it became #UseGuards(undefined) which caused the cryptic error message. Moving the guard to a dedicated file will fix the error
I follow your github reference settings and it doesn't work,The following is my code, where is my setting wrong, and the request to ws is not intercepted(In the handleRequest method)
I use rxjs and socket.io client.
Id like to solve this problem.
socket is connected
user send data
socket is having any network error during delivery
delivery is faled
socket throw error to user
Here is my code. how to handle network errors indise Observable?
private sendData(data: any, event: SOCKET_EVENTS): Observable<any> {
return new Observable<any>(observer => {
this.socket
.emit(event, data, function(responseData: Result<any>) {
console.log("Data sended", responseData);
if (responseData.success === true) {
observer.next(responseData.data);
observer.complete();
} else {
console.error(" this.socketData not sended", responseData);
observer.error(data);
}
})
});
}
You can handle errors globaly using event error or something else. For every single emit you can use acknowledgements. Anyway, procedure which handle errors should be more complex. For example:
private sendData(data: any, event: SOCKET_EVENTS): Observable<any> {
return new Observable<any>(observer => {
// set timeout before call error
let errorTimeout = setTimeout(() => {
console.error(" this.socketData not sended");
observer.error();
}, 5000);
this.socket
.emit(event, data, (responseData: Result<any>) => {
console.log("Data sended", responseData);
observer.next(responseData.data);
observer.complete();
// reset timer
clearTimeout(errorTimeout);
})
});
}
We wait 5 seconds for response with acknowledgement. Also you should add logic to handle global errors.
I'm using feathers with socketio in backend. The client is listening and everything works well.
I want to handle the 'server not responding' error and I don't find where can I do that?
The error thrown by the server:
"Unhandled promise rejection
Object { type: "FeathersError", name: "Timeout", message: "Timeout of 5000ms exceeded calling find on newsfeed", code: 408, className: "timeout", data: {…}, errors: {}, stack: "FeathersError#webpack-internal:///./node_modules/#feathersjs/errors/lib/index.js:58:19\nTimeout#webpack-internal:///./node_modules/#feathersjs/errors/lib/index.js:135:3\nsend/</timeoutId<#webpack-internal:///./node_modules/#feathersjs/transport-commons/lib/client.js:66:9\n" }"
It is correct, the 'promise' is not handled! Where do I handle?
I tried adding catch on each line just to see what works but without success:
import feathers from '#feathersjs/feathers'
import socketio from '#feathersjs/socketio-client'
import io from 'socket.io-client'
const socket = io('http://localhost:3030/', {transports: ['websocket']});
socket.on("connect_failed", er=>console.error('Error connecting to server: ', er));
const restApi = feathers()
.configure(socketio(socket));
try {
restApi.service('/newsfeed');
restApi.on("connect_failed", er=>console.error('Error connecting to server: ', er));
}
catch (er) {
console.error('Error connecting to server: ', er)
}
export default restApi
The timeout error is coming from a particular request so you have to handle it wherever you are making the request.
restApi.service('/newsfeed').find()
If you're using async/await, you can wrap your service call in a try/catch or my personal favorite is just putting a catch on the call;
// try/catch
try {
const response= await restApi.service('/newsfeed').find();
catch(e) {
// handle e
}
//just use catch
const response= await restApi.service('/newsfeed').find().catch(e => {
// handle e
});
If you're using promises, just use a catch:
restApi.service('/newsfeed').find().then(response => {
// handle response
}).catch(e => {
// handle e
});
I am trying to cover redux-saga that gets data from RxDB with Jest tests.
export function* checkUnsavedData(action) {
const { tab } = action;
try {
const db = yield getDB().catch(e => {
throw new Error(e);
});
const currentUser = yield select(makeSelectCurrentUser());
const unsavedData = yield db[USER_COLLECTION].findOne(currentUser)
.exec()
.then(data => data && data.unsavedData)
.catch(e => {
throw new Error(e);
});
} catch (error) {
yield showError(error);
}
}
Everything is fine in live run. But testing the generator I get:
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Error: RxError:
RxDatabase.create(): Adapter not added. Use RxDB.plugin(require('pouchdb-adapter-[adaptername]');
Given parameters: {
adapter:"idb"}
If anyone has done this, please, tell me how to test such cases with RxDB in redux-saga with Jest.
It looks like you did non add the adapter to RxDB. Can you paste the code where you create the database? This would help more in finding the error.
When running tests, you should not use the idb-adapter. Use the in-memory-adapter, it's faster and also you can be sure that you start on a clean state on each testrun.
I used app.authenticate on client.
It called the authentication hook in before create hook on server.
I imported from 'feathers-authentication-manage.hook' as verifyHooks.
Before create hook:
app.service('authentication').hooks({
before: {
create: [
authentication.hooks.authenticate(config.strategies),
async context => {
const { app, data } = context;
await app.service('users').find({
query: {
usernameUpperCase: data.username.toUpperCase(),
$limit: 1
}
})
.then(async (user) => {
await user.data.map(async data => {
if(!data.isVerified) {
await console.log('HELLO FROM ABOVE.');
//await v.validationError('Verify Email. A token link has been sent to your email.');
}
});
})
.catch(err => v.validationError(err));
},
verifyHooks.isVerified()
],
The 3 hooks in order were:
1. authentication
2. my hook
3. isVerified() email verify hook from feathers-authentication management
On client, the authenticate promise would be rejected when isVerified() hook activated even if was after the authentication hook.
If I removed the isVerified() hook, the authenticate promise would resolve.
How do I make my hook, the second hook, behave like isVerified() so the authenticate promise on client be rejected?
The first thing is that you are making your life harder by using async/await not as it is intended. The idea is to not having to write all those .then and .catch handlers.
The .catch handler is also probably where actual issue is. If a .catch (in your case v.validationError(err)) does not reject or throw an error, the promise will resolve successfully. Using async/await the right way and Promise.all to wait for the asynchronous validation steps and then re-throwing the validation error should do it:
app.service('authentication').hooks({
before: {
create: [
authentication.hooks.authenticate(config.strategies),
async context => {
const { app, data } = context;
const user = await app.service('users').find({
query: {
usernameUpperCase: data.username.toUpperCase(),
$limit: 1
}
});
try {
await Promise.all(user.data.map(async data => {
if(!data.isVerified) {
await console.log('HELLO FROM ABOVE.');
//await v.validationError('Verify Email. A token link has been sent to your email.');
}
});
} catch(err) {
throw v.validationError(err);
}
},