In angular we have something like mport {HttpClient, HttpErrorResponse, HttpHeaders} from "#angular/common/http";
so when we make a post call using http and Rxjs,like below code..we have something called ErrorEvent.
private runBuild(jobName: string, payload: string) {
return this.http.post(this.jenkinsURLs.runJobUrl(jobName), "json=" + encodeURIComponent(payload), httpOptions)
.pipe(catchError(this.handleError));
};
private handleError(error: HttpErrorResponse) {
let errorMessage: string = '';
***if (error.error instanceof ErrorEvent) {
errorMessage = 'An error occurred: ' + error.error.message;
} else {
errorMessage = `Jenkins returned code ${error.status}, body was: ${error.message}`;
}***
return throwError(errorMessage);
};
but in react, if I want to have different messages for different error codes, I have to do it manually because we don't have something like ErrorEvent.
COuld you please suggest any generic way to have some sort of ErrorEvent so that I can assign different message by validating the instanceOf operator in react
You can wrap < App /> (or at another relevant place to wrap just once) with < ErrorBoundary > that will be trigger to do something at componentDidCatch lifeCycle. {((error, errorInfo)} params at this lifeCycle can be the handlers of the fit error that suppose to be shown - https://reactjs.org/docs/error-boundaries.html
Related
I have a lwc component that subscribes to the event WhatsAppMessage, and I have been trying to filter the event platform but I have not been able to get the expected result, since it does not respect my filter and it brings me all the results
This is my JS Code when I suscribe
import { LightningElement } from 'lwc';
import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from
'lightning/empApi';
export default class PlatformEventMonitor extends LightningElement {
channelName = '/event/Sample__e';
isSubscribeDisabled = false;
isUnsubscribeDisabled = !this.isSubscribeDisabled;
subscription = {};
// Tracks changes to channelName text field
handleChannelName(event) {
this.channelName = event.target.value;
}
// Initializes the component
connectedCallback() {
// Register error listener
this.registerErrorListener();
}
// Handles subscribe button click
handleSubscribe() {
// Callback invoked whenever a new event message is received
const messageCallback = function(response) {
console.log('New message received: ', JSON.stringify(response));
// Response contains the payload of the new message received
};
// Invoke subscribe method of empApi. Pass reference to messageCallback
subscribe(this.channelName, -1, messageCallback).then(response => {
// Response contains the subscription information on subscribe call
console.log('Subscription request sent to: ', JSON.stringify(response.channel));
this.subscription = response;
this.toggleSubscribeButton(true);
});
}
// Handles unsubscribe button click
handleUnsubscribe() {
this.toggleSubscribeButton(false);
// Invoke unsubscribe method of empApi
unsubscribe(this.subscription, response => {
console.log('unsubscribe() response: ', JSON.stringify(response));
// Response is true for successful unsubscribe
});
}
toggleSubscribeButton(enableSubscribe) {
this.isSubscribeDisabled = enableSubscribe;
this.isUnsubscribeDisabled = !enableSubscribe;
}
registerErrorListener() {
// Invoke onError empApi method
onError(error => {
console.log('Received error from server: ', JSON.stringify(error));
// Error contains the server-side error
});
}}
What makes you think this would work? I don't recognise syntax for filtering like that? From what doc you took it?
You can set replay id to -1, -2 but you'll get all messages. https://developer.salesforce.com/docs/component-library/bundle/lightning-emp-api/documentation
You can filter them out manually in your app but it'll waste the daily limit of the events to can receive...
The proper way would be to define custom channel on top of your event. It's bit like writing a query/listview/report. But there is no UI for it, you'd have to craft a special JSON and send it to ord using tooling API.
https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_filter_section.htm
So I have this function which sends request to the API and I want to throw exception when requests fails:
async function getCampaigns() {
try {
const response = await api.get('/cars');
setSelectItems(
response.map((item: Car) => ({
label: item.carLabel,
value: item.carValue
}))
);
setLoading(false);
} catch (error: any) {
const exception = new Exception(error);
exception.kind = 'recoverable';
throw exception;
}
}
I created custom exception to handle errors in this code:
Exception.ts
type ExceptionType = 'nonrecoverable' | 'recoverable';
export class Exception extends Error {
public kind: ExceptionType;
constructor(message?: string, options?: ErrorOptions) {
super(message, options);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, Exception);
}
this.kind = 'nonrecoverable';
this.name = 'Exception';
}
}
However I am getting the following error whenever I get error response:
Unhandled Runtime Error
Exception: AxiosError: Request failed with status code 401
which is pointing at this line:
const exception = new Exception(error);
Not sure why is this happening and how can I throw the custom error like this?
EDIT:
So the actual problem here is that, when I catch the error and throw custom one based on the error caught I throw it again in the catch block. I think this results in the custom error that is being thrown uncaught.
And because the custom error is uncaught, in Next.js development mode I get this error Overlay telling me about unhandled error...
Even though I have ErrorBoundary component that works as inteded (so redirects to the error component) but still Next.js overlay is displayed. So I am not sure how should I handle the custom error inside catch block in this situation? Is this correct approach already and should I leave it as it is or is there some better wayt to do this?
I would like to add error handling in my apollo react app. I'm checking error
export enum ERROR_CODES {
ERROR_USER_NOT_EXIST = "ERROR_USER_NOT_EXIST"
}
export const getErrorMessage = (error: string): string | null => {
switch(error) {
case ERROR_CODES.ERROR_USER_NOT_EXIST:
return 'test error';
default:
return null;
}
}
and I want to show snackBar for errors which I have in switch case.
I understand that i can't do it with apollo-link-error because i want to show an error like react component and I don't want to add error handling for each query request in my components. Maybe exist way to do it in one point in my app and without apollo-link-error.
Use apollo-link-error ;)
Nobody forces you to only console.log() error or break a data flow. You can use it to "inject your hook" only, to be notified on errors.
You can wrap your app in some context provider - create a 'communication channel' - use it to write errors (from error link) and to render (read and clear) them in snackBar.
I am facing the below issue where I am trying to save JSON data coming from my API into an array of my Model object. However, when I console.log the array it prints "undefined". I even tried to print a simple array and it still says "undefined". I am not sure if I am missing anything here. My code is given below. Can some one please help as I am new to Angular 2 and TypeScript.
results : Array<Recipes> = new Array(20);
sample = ['one','two','three'];
getResults(): Observable<Recipes[]>{
return this.http.get('<my API here which works perfectly.>')
.map(this.extractData)
.catch(this.handleErrorObservable);
}
private extractData(res: Response) {
let body = res.json();
console.log(this.sample); **---> This prints undefined in console**
console.log(body);
console.log(body.pagination.count);
let total_no_of_results = body.pagination.count;
let no_of_results;
for(no_of_results = 0; no_of_results < total_no_of_results; no_of_results++) {
//this.results[no_of_results] = new Recipes();
this.results[no_of_results] = body.data[no_of_results].embed_url; **---> This gives "Cannot set property '0' of undefined" error and program exits**
//this.results.push(image);
}
console.log(this.results);
return this.results;
}
private handleErrorObservable (error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
If you want to use this inside extractData you need
.map(this.extractData.bind(this))
or
.map((data) => this.extractData(data))
otherwise this won't point to the current class' instance.
I'm new to Angular 2 and Observables so I apologise if my problem is trivial. Anyway I'm trying to test the Angular 2 HTTP Client using RxJS. Although I got it to work I need to add more logic to the service I'm currently working on. Basically I'd like to have a mapping function to convert the object I receive from the web service I'm connected to, to the model object I have in Angular.
This is the code that works:
import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import { Person } from '../models/person';
#Injectable()
export class PersonsService {
constructor(private http: Http) { }
private personsUrl = 'http://localhost/api/persons';
getPersons(): Observable<Person[]> {
return this.http.get(this.personsUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
if(res.status < 200 || res.status >= 300) {
throw new Error('Bad response status ' + res.status);
}
let body = res.json();
return body.data || {};
}
private handleError(error: any) {
let errMsg = error.message;
return Observable.throw(errMsg);
}
}
With the above code I have no problems whatsoever. The issue I'm having is that I'd like to map the object I'm getting from the service to the one I have in Angular i.e. Person. What I tried is to call another function from the extractData function that's being used by the .map function.
private extractData(res: Response) {
if(res.status < 200 || res.status >= 300) {
throw new Error('Bad response status ' + res.status);
}
let body = res.json();
// map data function
var data = this.mapData(body.data);
return data || {};
}
private mapData(data: any) {
// code to map data
}
Obviously the code above doesn't work as when this is referenced inside the extractData function, this does not refer to the PersonsService class, but it refers to a MapSubscriber object.
I don't know if it is possible to call an "external" function. It might be a silly thing but I can't find any information regarding this.
Instead of just passing the function reference use arrow functions to retain this
.map((res) => this.extractData(res))
Observable's map function allows you to pass a reference variable as a second argument on how should this actually work inside the higher-order function.
so the solution is
.map(this.extractData,this)
This way while passing the extractData function you are also passing the current class's this execution context to the higher-order function.
It will work.
Observable Doc Reference Link