I'm trying to call API using common HTTPSERVICE method, Strangely I'm getting response whenever the debugger is connected, but API is throwing Network Error when debugger is not connected.
React-Native Version: 0.63.2
axios verison: 0.18.0
const sendRequest = async (url, method, params, data={}, headers = {}) => {
try {
const options = {
url,
method,
params,
data,
headers,
}
console.log(options);
return await axios(options);
} catch (err) {
console.log("request error",err);
throw err;
}
}
function* HttpService(url, methodType, params, data, headerParams = {}) {
try {
const user = yield select(state => state.ssoReducer.user);
if (isTokenExpired(user.token)) {
yield call(getPingFedToken);
}
const signIn = yield select(state => state.ssoReducer);
const authToken = signIn.user?.token;
const headers = {
Authorization: `${authToken}`,
'SWAP-MOBILE-APP': true,
"Content-Type": "application/x-www-form-urlencoded",
...headerParams
};
return yield call(sendRequest, url, methodType, params, data , headers)
} catch (error) {
console.log("http error",error);
if (error.response.status === (403)) {
yield put({
type: SSO_FAILURE,
payload: "Unauthorised alert"
});
}
throw error;
}
}
export default HttpService;
enter image description here
From what I see, the problem is not in this part of the code.
I am suspecting the way you create headerParams.
here is what you need to do.
check all the global methods that you are using in this flow ex. URLSearchParams
make sure that they exist in the web component layer that is part of the JS engine related to the react-native version you are using.
why:
because, when you connect the debugger; you are not executing your JS code in the engine of React Native, but inside the one in the chrome you are debugging with.
this is a known issue in the react-native world, and to avoid it I suggest you use another debugger like https://infinite.red/reactotron
Related
I have a server that does the rendering of the component and returns an HTML when the request is made while rendering the server does a graphql call for a particular component which sometimes returns a 403 response.
Code:
const client = new ApolloClient({
link: new HttpLink({
uri: 'https://url/graphql',
fetch,
headers: {
'csrf-tokens': tokens,
Referer: header_referer,
},
}),
queryDeduplication: false
)}
export const getProperties = async () => {
try {
await client
.query({query, variables})
.then((response) => {
const data = response.data.properties;
if(response.error) {
throw new Error("Error encountered");
}
}
.catch((error) => {
console.log("gettProperites error")
})
} catch (err) {
console.log("Execution failed")
}
}
I'm making a graphql call inside the getProperties function and whenever I get a 403 error my pod crashes. I have wrapped the call inside try-catch block and added an additional if condition inside .then() to check for any error inside the response. Still, the 403 response is not caught and crashes the pod.
The above code is the overall structure of the code that I'm running, I have removed a few details that were not required to keep it small.
Try interceptors.
I can just tell for vue, but I think in react it's quite similar:
const link = createUploadLink({ uri: '/graphql' });
const errors = onError(({ networkError }) => {
if (networkError.statusCode === 403) {
// do something with 403 response code like:
router.push('/403');
}
else {
// do something with any other error response code
}
})
const apolloClient = new ApolloClient({
link: errors.concat(link),
...
})
// This request is responsible for getting the URL of the page that I will do web scrapping on
axios.post("https://async.scraperapi.com/jobs", {
apiKey: KEY,
url: URL,
}).then(data => {
getThePrice(data.data.statusUrl);
});
//This request is responsible for doing web scraping for the URL I got from the previous request
function getThePrice(scrapedURL) {
axios.get(scrapedURL).then(data => console.log(data));
}
The problem is, the second request is being called before the first one has ended so I'm not getting the result I'm expecting
I tried to do the 2 requests separately by getting the link first then applying on the second one and it works but now I need to do them together
Not sure if there is problem with the API itself or with network connection but this is how I would do it with async await. It is also helpful to catch the error with try catch statement so you can better understand it.
const handleRequests = async () => {
try {
const { data } = await axios.post('https://async.scraperapi.com/jobs', {
apiKey: KEY,
url: URL,
})
const { data: secondReqData } = await axios.get(data?.statusUrl)
console.log(secondReqData)
} catch (e) {
console.log(e)
}
}
I am building a react-native app, and I am starting to implement a more robust and sophisticated error-handling system, specifically for handling server errors when making http requests. Here is a basic example of how I am currently making http requests in my app.
I have a 'client.js' file which is essentially just a wrapper around axios. I have a 'get' method that looks like this:
const get = async (endpoint, config = {}) => {
try {
const result = await axios.get(domain + endpoint, config);
return result;
} catch (error) {
throw new Error(error.message);
}
};
Then, I have a file for each api endpoint that I need to access. For example, I have a 'posts.js' file, and in that file I have a 'getPosts' method:
const getPosts = async (userID, page, pageSize) => {
try {
const response = await client.get(
`${endpoint}?userID=${userID}&page=${page}&pageSize=${pageSize}`
);
return response.data;
} catch (error) {
throw new Error(error.message);
}
};
And then finally, in the component that is calling getPosts, I have a function that looks something like this:
const loadPosts = async () => {
try {
const response = await getPosts();
// do something with the response from the server
} catch (error) {
// display an error message to the client
}
}
Obviously this is a very simple example of what a request might look like, but this is the basic structure that I use throughout my app. The problem I am having is that it seems very repetitive and messy to have to wrap almost all of my functions in a try/catch block, and then basically raise an error object until I get to the function that is actually going to handle the error. Is there some sort of 'design method' for error handling that simplifies and centralizes this process? Perhaps something similar to an express-middleware when creating a node server? Or is this a standard way to handle errors in javascript?
Thank you to anyone who can help!
As you are using axios as the http library here, so you can take a look at axios interceptor in order to hook the response and do something with that before passing it to the consumer. This will help you to respond to errors raised from once cental place.
axios.interceptors.response.use((response) => {
return response;
}, function(error) {
// do what you want to do with the error.
return Promise.reject(error)
});
Or with ES5 syntax
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Not 200 Ok
// Do something with response error
return Promise.reject(error);
});
So I am implementing axios call cancelation in the project. Right now looking at axios documentation it seems pretty straight forward https://github.com/axios/axios#cancellation
So I did define variables on the top of my Vue component like
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
obviously on top of that is import axios from 'axios';
Then I have a method of fetching the API
On the top of the method I want to cancel out the request in case it is running so the last one cancels out if the user spams the filtering.
async fetchPartners(inputToClear) {
source.cancel();
...
try {
const response = await axios.get(`../partners?limit=1000${this.createRequestString()}`, {
cancelToken: source.token
});
// Here you can see I did add the cancelToken to the request
this.partners = response.data.data;
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request canceled', error.message);
}
const fetchErrors = this.utilGlobalHandleErrorMessages(error);
this.utilGlobalDisplayMessage(fetchErrors.message, { type: 'error' });
return [];
} finally {
...
}
},
So it is pretty straight forward, just took the code from axios documentation I gave you above, it should be working by logic. But what is actually happening, it doesn't even allow me to fetch the call, it is already cancelled out before I can call it. On console it shows me
Request canceled undefined
It just catches the error as if I am cancelling the call, but how can it be, because I am source.cancel() before the call.
Anyone has any idea?
I hope you should throttle your requests instead of canceling the request.
Could you please try the following if throttle does not suit your requirement?
const CancelToken = axios.CancelToken;
let source;
async fetchPartners(inputToClear) {
if(source){
source.cancel();
}
...
source = CancelToken.source();
try {
const response = await axios.get(`../partners?limit=1000${this.createRequestString()}`, {
cancelToken: source.token
});
// Here you can see I did add the cancelToken to the request
this.partners = response.data.data;
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request canceled', error.message);
}
const fetchErrors = this.utilGlobalHandleErrorMessages(error);
this.utilGlobalDisplayMessage(fetchErrors.message, {
type: 'error'
});
return [];
} finally {
...
}
}
Really odd issue I am having. For some reason my put in my catch block is not being executed below. Here's my saga:
function* postLoginFormSaga(action) {
let response;
try {
// Data from emitting login action
response = yield call(AuthenticationApi.login, action.formData);
yield put(createLoginSucceedAction());
yield put(push('/dashboard/summary'));
} catch (e) {
console.log(e);
yield put(createLoginFailAction(response))
}
}
And my api call, which has a custom middleware to handle non 2XX responses:
static login = (formData) => {
return fetch('/api/login', {
method: 'POST',
body: formData,
credentials: 'same-origin'
}).then(handleFetchErrorMiddleWare)
.then(r => r.json())
};
Where the middleware function is a simple function that checks the ok property of the response object:
export function handleFetchErrorMiddleWare(response) {
if (!response.ok){
throw Error(response.status)
}
return response
}
The middleware is working correctly as I can see the output of the console.log(e) when an exception is thrown, but the yield put(createLoginFailAction(response)) is not being emitted ...
See below:
Any ideas? Thanks
Seems to me like there is an error in the createLoginFailAction function, if so that would cause the result that you are seeing.