가져오기: 상태가 정상이 아닐 경우 약속을 거부하고 오류를 잡습니까?
제가 할 일은 이렇습니다.
import 'whatwg-fetch';
function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
throw(error);
})
});
};
}
function status(res) {
if (!res.ok) {
return Promise.reject()
}
return res;
}
편집: 그 약속은 거절당하지 않습니다. 그것이 제가 이해하려는 것입니다.
리덕스에서 이 페치 폴리필을 리덕스 약속 미들웨어와 함께 사용하고 있습니다.
가져오기 약속은 네트워크 오류가 발생할 때만 TypeError와 함께 거부합니다.4xx와 5xx 응답은 네트워크 오류가 아니기 때문에 잡을 것이 없습니다.사용하려면 직접 오류를 던져야 합니다.Promise#catch
.
fetch Response는 요청이 성공했는지 여부를 알려주는 를 편리하게 제공합니다.이와 같은 것이 효과가 있을 것입니다.
fetch(url).then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Something went wrong');
})
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
다음의login with username and password
예제에서는 다음을 수행하는 방법을 보여 줍니다.
- 확인.
response.ok
reject
문제가 없다면 오류를 던지는 대신- 검증 문제와 같은 서버의 오류 힌트를 추가로 처리합니다.
login() {
const url = "https://example.com/api/users/login";
const headers = {
Accept: "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify({
email: this.username,
password: this.password,
}),
})
.then((response) => {
// 1. check response.ok
if (response.ok) {
return response.json();
}
return Promise.reject(response); // 2. reject instead of throw
})
.then((json) => {
// all good, token is ready
this.store.commit("token", json.access_token);
})
.catch((response) => {
console.log(response.status, response.statusText);
// 3. get error messages, if any
response.json().then((json: any) => {
console.log(json);
})
});
},
모두 도와주셔서 감사합니다. 약속을 거부합니다..catch()
내 문제 해결:
export function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
return Promise.reject()
})
});
};
}
function status(res) {
if (!res.ok) {
throw new Error(res.statusText);
}
return res;
}
저는 fny 답변이 정말로 모든 것을 받았습니다. fetch는 오류를 던지는 것이 아니기 때문에 우리는 오류를 직접 던지거나 처리해야 합니다.내 솔루션을 비동기식/대기식으로 게시합니다.제 생각에는 좀 더 앞으로 다가가서 읽을 수 있는 것 같아요.
해결책 1: 오류를 던지는 것이 아니라, 오류를 우리가 직접 처리합니다.
async _fetch(request) {
const fetchResult = await fetch(request); //Making the req
const result = await fetchResult.json(); // parsing the response
if (fetchResult.ok) {
return result; // return success object
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
const error = new Error();
error.info = responseError;
return (error);
}
여기서 오류가 발생하면 오류 객체인 일반 JS 객체를 만들고 반환하는 것인데, 문제는 외부에서 처리해야 한다는 것입니다.사용방법:
const userSaved = await apiCall(data); // calling fetch
if (userSaved instanceof Error) {
debug.log('Failed saving user', userSaved); // handle error
return;
}
debug.log('Success saving user', userSaved); // handle success
해결책 2: 오류 던지기, try/catch 사용하기
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
let error = new Error();
error = { ...error, ...responseError };
throw (error);
}
Error Cector에서 문자열만 승인하므로 일반 Error js 개체를 생성하므로 다음과 같이 생성할 수 있습니다.
try {
const userSaved = await apiCall(data); // calling fetch
debug.log('Success saving user', userSaved); // handle success
} catch (e) {
debug.log('Failed saving user', userSaved); // handle error
}
해결책 3: 고객 오류 사용
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
throw new ClassError(result.message, result.data, result.code);
}
그리고:
class ClassError extends Error {
constructor(message = 'Something went wrong', data = '', code = '') {
super();
this.message = message;
this.data = data;
this.code = code;
}
}
도움이 됐길 바랍니다.
2021 TypeScript Answer
제가 하는 일은 a를 쓰는 것입니다.fetch
일반적인 것을 취하는 포장지 그리고 만일.response
가ok
그것은 자동으로 될 것입니다..json()
그리고 type assert 결과를 입력합니다. 그렇지 않으면 포장지는 다음을 던집니다.response
export const fetcher = async <T>(input: RequestInfo, init?: RequestInit) => {
const response = await fetch(input, init);
if (!response.ok) {
throw response;
}
return response.json() as Promise<T>;
};
그리고 나서 오류를 잡아내고 그것들이 그들의 것인지 확인할 것입니다.instanceof
Response
. 그런 식으로 TypeScript는error
가지다Response
등의 속성status
statusText
body
headers
등과 나는 각각의 맞춤형 메시지를 적용할 수 있습니다.4xx
5xx
상태 코드.
try {
return await fetcher<LoginResponse>("http://localhost:8080/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ email: "user@example.com", password: "passw0rd" }),
});
} catch (error) {
if (error instanceof Response) {
switch (error.status) {
case 401:
throw new Error("Invalid login credentials");
/* ... */
default:
throw new Error(`Unknown server error occured: ${error.statusText}`);
}
}
throw new Error(`Something went wrong: ${error.message || error}`);
}
만약 네트워크 에러와 같은 것이 발생한다면 그것은 외부에서 잡힐 수 있습니다.instanceof
Response
보다 일반적인 메시지로 확인합니다.
throw new Error(`Something went wrong: ${error.message || error}`);
@fny(받아들인 대답)라는 대답은 저에게 통하지 않았습니다.throw new Error()
그들은 그들에게 납치당하지 않았습니다..catch
. 내 해결책은 포장하는 것이었습니다.fetch
새로운 약속을 구축하는 기능으로:
function my_fetch(url, args) {
return new Promise((resolve, reject) => {
fetch(url, args)
.then((response) => {
response.text().then((body) => {
if (response.ok) {
resolve(body)
} else {
reject(body)
}
})
})
.catch((error) => { reject(error) })
})
}
이지 않은 은 될 것입니다..catch
방법:
my_fetch(url, args)
.then((response) => {
// Do something with the response
})
.catch((error) => {
// Do something with the error
})
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("https://example.com/api/users")
.then(handleErrors)
.then(response => console.log("ok") )
.catch(error => console.log(error) );
대부분의 답변에 공감을 주는 또 다른 (짧은) 버전:
fetch(url)
.then(response => response.ok ? response.json() : Promise.reject(response))
.then(json => doStuff(json)) //all good
//next line is optional
.catch(response => handleError(response)) //handle error
제안한 솔루션 중 어느 것도 만족스럽지 못하여 Fetch API로 성공 응답과 오류 응답을 모두 처리할 수 있는 방법을 찾아 보았습니다.
계획은 다음과 같습니다.{status: XXX, message: 'a message'}
두 경우 모두 결과적으로 형식이 지정됩니다.
참고: 성공 응답에 빈 본문이 포함될 수 있습니다.그런 경우 우리는 뒤로 물러나서 사용합니다.Response.status
그리고.Response.statusText
결과 응답 개체를 채울 수 있습니다.
fetch(url)
.then(handleResponse)
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
export const handleResponse = (res) => {
if (!res.ok) {
return res
.text()
.then(result => JSON.parse(result))
.then(result => Promise.reject({ status: result.status, message: result.message }));
}
return res
.json()
.then(result => Promise.resolve(result))
.catch(() => Promise.resolve({ status: res.status, message: res.statusText }));
};
이것이 내가 던지는 데 도움이 되기를 바랍니다 오류가 작동하지 않습니다.
function handleErrors(response) {
if (!response.ok) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({
status: response.status,
statusText: response.statusText,
});
}, 0);
});
}
return response.json();
}
function clickHandler(event) {
const textInput = input.value;
let output;
fetch(`${URL}${encodeURI(textInput)}`)
.then(handleErrors)
.then((json) => {
output = json.contents.translated;
console.log(output);
outputDiv.innerHTML = "<p>" + output + "</p>";
})
.catch((error) => alert(error.statusText));
}
부울당 성공적인 응답(상태 200 - 299)을 나타내는 -ok 속성을 사용하여 응답 개체의 상태를 확인했습니다.
$promise.then( function successCallback(response) {
console.log(response);
if (response.ok) { ... }
});
언급URL : https://stackoverflow.com/questions/38235715/fetch-reject-promise-and-catch-the-error-if-status-is-not-ok
'programing' 카테고리의 다른 글
"본래 스레드 세이프(thread-safe)"란 무엇을 의미합니까? (0) | 2023.10.05 |
---|---|
일치하지 않는 익명 정의() 모듈 (0) | 2023.10.05 |
폼을 편집할 때마다 확인하기 위해 $dirty in angularjs 사용 (0) | 2023.10.05 |
LINQ의 Select 명령에 해당하는 파워셸? (0) | 2023.10.05 |
sigprocmask()에서 Set and Oldset(설정 및 이전 설정) (0) | 2023.10.05 |