Я использую VueJs (и Vuex) с Axios для связи с Express Api. Я могу удалить свою учетную запись пользователя, использующую службу
import api from '@/services/api.js';
export default {
deleteAccount: () => api().delete('/users')
};
где api
— экземпляр axios
. Мне не нужно передавать идентификатор пользователя, потому что API идентифицирует пользователя по жетон.
В моем представлении настроек я могу использовать эту услугу
<script>
import { mapActions } from 'vuex';
import UserService from '@/services/users';
export default {
name: 'Settings',
methods: {
...mapActions('alert', [
'showSuccessAlert',
'showErrorAlert'
])
deleteAccount: async function() {
try {
await UserService.deleteAccount();
this.showSuccessAlert({ message: 'Account was deleted successfully' });
// other stuff
} catch (error) {
this.showErrorAlert({ message: error.message });
}
}
}
};
</script>
Звонок UserService.deleteAccount()
возвращает мне невыполненное обещание. Использование await
возвращает мне ответ API.
В настоящее время API всегда возвращает 500
для целей тестирования. Я думал, что если Promise будет отклонен, код всегда будет переходить прямо в блок catch. Здесь код возвращает отклоненное обещание (и записывает «Внутреннюю ошибку сервера» в консоль, но проходит и показывает предупреждение об успешном выполнении / никогда не выполняет код из блока catch.
Что не так с кодом? Я неправильно понял обещания?
Обновлять
Мой экземпляр axios
import axios from 'axios';
import TokensService from '@/services/tokens.js';
import store from '@/store/store.js';
function getTokenString() {
return `Bearer ${TokensService.getToken()}`;
}
export default () => {
const instance = axios.create({
baseURL: 'http://localhost:3000/',
headers: {
'Content-Type': 'application/json',
Authorization: getTokenString(),
},
});
instance.interceptors.request.use((config) => {
config.headers.Authorization = getTokenString();
return config;
}, (err) => Promise.reject(err));
instance.interceptors.response.use((res) => res, (err) => {
if (err.response.status === 401) {
store.dispatch('authentication/destroySession');
store.dispatch('alert/showErrorAlert', { message: err.message });
}
return err;
});
return instance;
};
Позвонить api().delete()
— это то же самое, что axios.delete('http://localhost:3000/users')
Возвращает ли код состояния 500 автоматическое отклонение обещания?
да нормально так и есть
как выглядит код для api().delete
? это твой код?
насколько я знаю, все "неудачные запросы" попадут в блок catch
насколько вы знаете ... явно нет :p опять же, это код api().delete
твой? Если нет, то что это
статус 500 - это не неудачный запрос, это ошибка сервера. Это успешный запрос с кодом состояния, указывающим, что логика на сервере, стоящая за запросом, не удалась. Что касается браузера, сам запрос по-прежнему выполнен успешно, поэтому он не вызовет автоматического отклонения. Например, API fetch(), о котором упоминает Яро.
@JaromandaX да, это мой код, я обновлю свой ответ
попробуйте вернуть отклоненное обещание здесь
instance.interceptors.response.use((res) => res, (err) => {
if (err.response.status === 401) {
store.dispatch('authentication/destroySession');
store.dispatch('alert/showErrorAlert', { message: err.message });
}
return Promise.reject(err);
});
по примерам https://github.com/axios/axios#interceptors
о да, мне пришлось изменить return err;
на return Promise.reject(err);
returns a 500
- статус http не обязательно означает отклоненное обещание - браузерыfetch
, например, не отклоняют 500 или 404 или любой успешный (вплоть до получения ответа http) запрос