I am using axios to make a HTTP get a call, if I specify an invalid URL axios runs the .then() as if it was successful. How to I get it to error if it can't find the url
import React, { Component } from "react";
import axios from "axios";
export default class AxiosRequest extends Component {
render() {
axios
.get("invalidurl")
.then(response => {
console.log("Axios request successful...or was it, No it wasnt");
})
.catch(err => {
console.log("Axios request error", err);
});
return <h1>Axios Request</h1>;
}
}
Running sandbox to show the issue.
https://codesandbox.io/s/9lmn7316kp
The reason for this is if you open the "Network" console in you web browser, you will see the request being made is to the webpage you are currently on (the sandbox), thus returning a 200. If you put in a real url such as http://google.com/ you will see the correct return.
Related
I am currently working on a React Native project.
My code is this:
const onSubmit = async ({email, password}) => {
const url = 'https://gravitee.****.com:***/***/api/auth/signin';
try {
const response = await axios.post(url, {
email,
password,
registrationSource: SOURCE,
});
console.warn(response);
} catch (error) {
console.warn('err: ', error);
}
};
I have made this project on React as well and this is working well there. But on React Native it gives me Network Error. Nothing else. I tried with fetch api, it didn't work either. And what's interesting is I can fetch data from an external api that I just found on web. So what could be the problem? By the way i am running app on ios simulator and my device is Mac M1
Full error is like this:
err: AxiosError: Network Error
Call Stack
onSubmit
index.js: 87:7
asyncGeneratorStep
asyncToGenerator.js: 3:16
\_throw
asyncToGenerator.js: 29:27
tryCallOne
internalBytecode.js: 53:16
anonymous
internalBytecode.js: 139:27
I tried sending request to gravitee with axios and fetch and expecting login data of the user.
At this moment i'm using a response interceptor instance.interceptors.response.use for global error handling. In that function i'm redirecting in case of a 404, i'm clearing the storage in case of a 401 etc. Which works fine :)
Except now I've got a spot where i want to handle the 404 error differently, but a simple try/catch or a .catch won't work since the axios interceptor intercepts the response and redirects immediately.
Whats the best practice in this situation?
Not using the interceptor for global error handling? (but then what? call a handleError kind of function after every request except this one?)
Temporary turn it off somehow
Pass an ignore404 option or something with the axios request (although I use a function per request so i can't do this really simple)
What would be the best, but i'm not sure how is that axios is always doing some global error reporting except when you catch it yourself. And at that point at the bottom of the catch i could let the global error handler do it's job anyway if i want to
My interceptor:
function onResponseRejected(error) {
const { response } = error;
if (!response) return Promise.reject(error); // network error, not axios related
const { status } = response;
const { errors } = response.data;
if (status === 403) {
router.push({ name: '403' });
} else if (status === 404) {
router.push({ name: '404' });
}
....
....
My axios requests
export const fetch = (some) => {
return get(`some/${someId}/url/`)
}
My application usage of a request
const response = fetch(this.$route.params.connectorId, this.$route.params.mapperId).catch(() => {
console.log('At this moment the request will be redirected to another route...');
});
i am building a simple lyrics finder app using react.js and using musixmatch api. when i request the api i get this error in consoleError: Request failed with status code 403 at createError (createError.js:16) at settle (settle.js:17) at XMLHttpRequest.handleLoad (xhr.js:62)
this is my componentDidMount() function
import React, { Component } from 'react';
import axios from 'axios';
const Context = React.createContext();
export class Provider extends Component {
state = {
track_list: [],
heading: "Top 10 Tracks"
}
componentDidMount() {
axios.get(
`https://cors-anywhere.herokuapp.com/https://api.musixmatch.com/ws/1.1/chart.tracks.get?chart_name=top&page=1&page_size=5&country=it&f_has_lyrics=1&apikey=${
process.env.REACT_APP_MM_KEY}`
)
.then(res => console.log(res.data))
.catch(err => console.log(err));
}
render() {
return (
<Context.Provider value={this.state} >
{this.props.children}
</Context.Provider>
);
}
}
export const Consumer = Context.Consumer;
status code 403 means that you are not authorized. You could either have entered a wrong api key or maybe your process.env does not work (try to enter the api key directly!).
And are u sure that you need cors-anywhere? Did you try without?
EDIT:
you can test if your api key works when you simply enter the url with your key into the browser (without cars-anywhere) like so:
https://api.musixmatch.com/ws/1.1/chart.tracks.get?chart_name=top&page=1&page_size=5&country=it&f_has_lyrics=1&apikey=your_api_key
EDIT 2:
this works, when I try it inside a React application: So the problem must be at your process.env implementation.
componentDidMount() {
axios.get(
`https://cors-anywhere.herokuapp.com/https://api.musixmatch.com/ws/1.1/chart.tracks.get?chart_name=top&page=1&page_size=5&country=it&f_has_lyrics=1&apikey=your_api_key`
)
.then(res => console.log(res.data))
.catch(err => console.log(err));
}
From my experience, it was problem with axios version. so if you tried all solutions and still can not find the root cause, you can try to change axios version. I was using was assume role credentials to make a request against a service and always getting rejected with 403 even though the credentials were correct. I was using axios 1.3.1 but then I downgraded it to 0.27.2 and now my code is working fine
If you are not using an API key, you might have exhausted your request. You only get about 50 request thereabout per hour or something like, except you use an API key
I have a react component and I'm making a network call to set the state. Eventually I want to pass this down to other child components, but just getting the plumbing to work at the moment.
I'm trying to catch errors correctly when calling out to my backend (an express server in the app). I attempted to force an error by fetching data from an endpoint that doesn't exist. This should throw a 404 since it doesn't exist, right? How can I get that error surfaced in the catch statement? Right now my error is SyntaxError: Unexpected token < in JSON at position 0 at eval (app.js:61)
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
fetch('/api/wrong_endpoint').then((data) => {
return data.json();
}).then((body) => {
this.setState({data: body})
}).catch(err => console.log(err));
}
render() {
console.log('logging the states');
console.log(this.state.data);
return (
<div>
<ContactList />
<ContactDetail />
<AddContactModal />
</div>
);
}
}
I'll try to go step by step
fetch method doesn't throw an error even if you get the 4xx or 5xx response codes. Please read about the Fetch API carefully, I believe you can find a lot of interesting you don't know about it.
You can easily check the response status as follows (please read about the Response object and its methods/properties):
fetch('/api/wrong_endpoint').then((response) => {
console.log('status code', response.status)
})
It's hard to say if your server really returns 404 code because I don't know your express setup. If you set some fallback handler like app.get('*', ...) then it might as well return 200 success code. You can check the response status and its body in devTools of the browser. But I believe it's better if you configure at least your /api router to return 404 error if the requested /api/... route isn't found.
What I'm really sure of is that your server returns some HTML layout in the response. And you try to parse it as JSON string via data.json() and of course you get the syntax error since it's not JSON (html layout starts with < symbol hence the error: SyntaxError: Unexpected token <)
Generally, if you are using the fetch API, errors 40x and 50x will not go into the subsequent blocks, as the promise from fetch only rejects network errors (not HTTP errors or anything else). Therefore, requesting for data from an 'incorrect' endpoint will be handled within the first then block.
I would recommend you to use check your http response body based on the Response.Ok property. Successful responses will be handled within that condition, whereas any other responses (ok: false) will be handled on the other statement.
fetch('/api/wrong_endpoint')
.then(response => {
console.log(response) // full response body
console.log(response.status); // get only the response.status
if (!response.ok) {
// http errors 40x and 50x will go into this statement
// do something to handle it
} else if (response.ok) {
// handles status code 200
}
})
.then(
// ...
I am developing an application using React js in Redux architecture
and used axios for http requests.
I have two container classes one is login and another one is home
page. In routes class i import both the container classes.
In home page container i import one action and that action imports
one axios instance variable
export var Instance_Variable = axios.create({
baseURL: URL,
headers: {
"AUTH-TOKEN": localStorage.getItem("AuthToken")
}
});
In my scenario,
the routs file will import these instance variable while importing home page class.
While login i get the auth token from the response and set it to the local storage. After logging in there was one request made in home page and respond with unauthorized(401 - The auth token validation done in application).
I am view the network tab in browser and the request made with the header "AUTH-TOKEN" : null
How do i update the instance after logging in to the application
Note: The request are works well after refreshing the application after loggin
Hello I know it’s a very old question but today I also faced this same issue and Hopefully able to solve this problem also
So, when you call the 'login API URL with Axios, if this request succeeded then you have set the header in Axios '.then' block like they said here
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
Note: for this, you must have to use Axios interceptor
It is better to use an axios interceptor that sets header for every request like below:
axios
.interceptors
.request
.use(function (config) {
if (cookie.load('auth-token')) {
config.headers['AUTH-TOKEN'] = cookie.load('auth-token');
}
return config;
}, function (error) {
return Promise.reject(error);
});