I have an angular 2 service
import * as localforage from "localforage";
import { ReplaySubject } from 'rxjs/ReplaySubject';
#Injectable()
export class CommentService {
private localForage = require("localforage");
addComment (myvalue: string): Observable<Comment[]> {
var reply:ReplaySubject<any> = new ReplaySubject(1);
localforage.setItem(that.key, that.elencoCommenti).then(function (value) {
//throw new Error("Value cannot be 3");
reply.throw(Error('Error2'));
// reply.next( value );
// reply.complete();
});
return reply;
}
}
This service cointains a method for raise an exception.
When i try to subscribe
submitComment(){
// Variable to hold a reference of addComment
let commentOperation:Observable<string>;
commentOperation = this.commentService.addComment(this.model)
// Subscribe to observable
commentOperation.subscribe(
comments => {
console.log('ok:');
console.log(comments);
},
err => {
// Log errors if any
console.log('error:');
console.log(err);
});
}
i don't receive the error.
How raise exception in ReplaySubject?
reply.error("some error"); should do it.
However I would not suggest you to throw an error in a ReplaySubject - as any error will finalize the Subject and make it unusable for any future use and will automatically unsubscribe any subscribers - unless that is what you want to achieve here.
Related
I would like to return the UUID(v4) created for each request in nestjs as a response to the request.
I want to return the UUID(v4) that nestjs creates for each request as the response to the request.
However, I am using rabbitmq.
Is there any other way to return the UUID after going through rabbitmq for each request?
With this method, I am creating a connection for each request.
I want to create the connection only once after nestjs is started.
Also, any other method using other libraries would be good.
import { Controller, Get } from '#nestjs/common';
import { v4 as uuidv4 } from 'uuid';
#Controller('cats')
export class CatsController {
#Get()
findAll(): string {
const sequence = uuidv4(); // I want to return this.
return 'This action returns all cats';
}
}
...
await channel.consume(queueName, async (data: any) => {
if (queueName === 'testQueue') {
// do something.
}
});
I created a simple api endpoint named getFeed which is supposed to get feed content from Sanity CMS. But unexpectedly the endpoint is throwing an error "res.status is not a function". I know there is a similar question asked here , but in my case the api endpoint file is stored in the supposed pages/api directory. Here is the code snippet below.
import { NextApiResponse } from 'next'
import { client } from '../../lib/sanity/sanity'
export default async function getFeed(res: NextApiResponse) {
try {
const feeds = await client.fetch(
`*[_type == "post"]
{
_createdAt,
title,
description,
picture,
postDocId,
postedByUserId,
postedByUserName,
postedByUserImage
}`
)
return res.status(200).json({ feeds })
} catch (error) {
return res.status(500).json({ message: "Couldn't get post feed:\n", error })
}
}
Here is my folder structure
What am I doing wrong??
Try to specify also the req parameter and add a type to the response:
import { NextApiRequest, NextApiResponse } from 'next'
interface Data {
message?: string;
feeds?: <type-of-feeds>[];
}
export default async function getFeed(req: NextApiRequest, res: NextApiResponse<Data>) { ... }
I successfully implemented a jwt strategy for authentication using nestJs.
Below is the code for the jwt strategy
import { ServerResponse } from './../helpers/serverResponse.helper';
import { Injectable, UnauthorizedException, HttpStatus } from '#nestjs/common';
import { PassportStrategy } from '#nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { config as env } from 'dotenv';
import { Bugsnag } from '../helpers/bugsnag.helper';
env();
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(
private readonly logger: Bugsnag,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET_KEY,
passReqToCallback: true,
});
}
async validate(payload, done: Function) {
try {
const validClaims = await this.authService.verifyTokenClaims(payload);
if (!validClaims)
return done(new UnauthorizedException('invalid token claims'), false);
done(null, payload);
} catch (err) {
this.logger.notify(err);
return ServerResponse.throwError({
success: false,
status: HttpStatus.INTERNAL_SERVER_ERROR,
message: 'JwtStrategy class, validate function',
errors: [err],
});
}
}
}
I saw here that the validate function will be called only when a valid token was provided in the request headers and I'm okay with that. However, I would like to know if it is possible to customize the response object which is sent in that case (invalid token provided).
If yes, how do I do that ?
You can use a exception filter to catch UnauthorizedExceptions and modify the response there if you'd like. The other option would be extending the AuthGuard('jwt') mixin class and adding in some logic around a try/catch for the super.canActivate(context), then in the error read what the reason is and throw a specific UnauthorizedException with your custom message
You can use the AuthGuard('jwt')'s handleRequest method to throw any exception on JWT Validation failure.
#Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
handleRequest(err: any, user: any, info: any, context: any, status: any) {
if (info instanceof JsonWebTokenError) {
throw new UnauthorizedException('Invalid Token!');
}
return super.handleRequest(err, user, info, context, status);
}
}
JsonWebTokenError comes from jsonwebtoken library, which is used internally by passport.
I want the user to be automatically logged out if any api returns a 401 error response.And to do that I am intercepting every request and as soon as the error code comes 401 I am clearing the jwt token in my local storage and auth guard prevents the user from jumping to that route.But after implementing the interceptor(examples are very less for this and no mention in the docs as well) I am unable to hit any HTTP request.Below is my code.Thanks in advance.
import { Injectable, Injector } from '#angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse} from '#angular/common/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/observable/throw'
import 'rxjs/add/operator/catch';
#Injectable()
export class ResponseInterceptor implements HttpInterceptor {
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).do((event: HttpEvent<any>) => {
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
// do error handling here
console.log('and the error is ');
console.log(err)
}
});
}
}
If it goes with error why you need to track every request if you could only catch needed?
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((err:string, caught:Observable<any>)=>this.handleHttpClientError(err, caught))
);
}
handleHttpClientError(error: any, caught: Observable<any>)
{
if(error.status == 401){
... your logic here ...
}
return new EmptyObservable<Response>();
// or return Observable.throw('Auth error');
}
I've created global error handler in my Angular 6 application:
main error handler method:
handleError(error: Error | HttpErrorResponse) {
const router = this.injector.get(Router);
const notificationService = this.injector.get(NotificationsService);
this._logger(error);
if (!navigator.onLine) {
notificationService.displayNotification('error', 'timespan', {heading: 'Internet connection lost!', body: ''});
} else if (error instanceof HttpErrorResponse) {
notificationService.displayNotification('error', 'click', this._httpErrorMessage(error));
} else {
// CLIENT error
router.navigate(['/error-page']);
}
}
Problem:
Many of HTTP service calls are being performed in resolvers:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ClientDetailsModel> {
if (route.params.cif) {
const reqBody = new GetClientDetailsRequestModel({cif: route.params.cif, idWewPrac: this.userContext.getUserSKP()});
return this.clientsService.getClientDetails(reqBody)
.pipe(
map((clientDetails: { customerDetails: ClientDetailsModel }) => {
if (clientDetails.customerDetails) {
return clientDetails.customerDetails;
}
return null;
})
);
}
If Http error occurs in such a call, error received by my global error handler is formed as HttpErrorResponse wrapped inside Error (message of Error is HttpErrorResponse):
Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":400,"statusText":"OK","url":"https://...
If Http errors occurs outside of resolvers global error handler works perfectly fine.
To reach my goal (throwing HttpErrorResponse from resolver) I need to specify the way to handle error in error callback inside subscription, but I cannot do it because resolver is the one who manages subscription.
Is there a way to specify how resolver should handle errors?
I would like to avoid manual parsing of these wrapped errors.
I was searching for a solution, but could only create a work-a-round.
This will check for the HttpErrorResponse text and tries to parse the JSON which results into the real error object.
Not great at all, but better then nothing.
handleError(error: any): void {
console.error('Errorhandler catched error: ' + error.message, error);
// We need to have this little hack in oder to access the real error object
// The Angular resolver / promise wraps the error into the message, serialized as json.
// So we extract this error again.
// But first lets check if we actually dealing with an HttpErrorResponse ...
if (error.message.search('HttpErrorResponse: ')) {
// The error includes an HTTPErrorResponse, so we try to parse it's values ...
const regex = new RegExp('^.*HttpErrorResponse:\\s(\\{.*\\})$');
const matches = regex.exec(error.message);
if (matches !== null) {
// matches the regex, convert...
const httpErrorResponse = JSON.parse(matches[1]); // This is now the real error object with all the fields
this.handleHttpErrorResponse(httpErrorResponse);
} else {
// It contains HttpErrorResponse, but no JSON part...
this.toastr.error('There was an unknown communication error',
'Communication error',
{timeOut: 10000});
}
} else {
this.toastr.error('Unknown error occured',
'Well that should not happen. Check the log for more information...',
{timeOut: 10000});
}
}