axious エラーハンドリングについて考える


今回対象となるコード
```typescript
const handleSubmit = async(event : React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setFieldErrors({});
    try {
      const response = await axios.post('http://localhost:4000/signUp', formData);
      console.log("this is response of form" , response);
      console.log("response is received");
      setFormData({
        username : "",
        password : "",
        retypePassword : ""
      });
    } catch (error) {
//ここのエラーハンドリングについて考える。
//またフロントのエラーによる表示処理をしたいので、stateでerrorオブジェクトとして管理する
  }
```

axiousのソースを確認すると、以下のようになる
```ts
export interface AxiosStatic extends AxiosInstance {
  create(config?: AxiosRequestConfig): AxiosInstance;
  Cancel: CancelStatic;
  CancelToken: CancelTokenStatic;
  isCancel(value: any): boolean;
  all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
  spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
  isAxiosError(payload: any): payload is AxiosError;
}

declare const axios: AxiosStatic;
```

ここでは**Axious**について確認すると、

```ts
export interface AxiosError<T = any> extends Error {
  config: AxiosRequestConfig;
  code?: string;
  request?: any;
  response?: AxiosResponse<T>;
  isAxiosError: boolean;
  toJSON: () => object;
}
```
このように定義されており
```ts
get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
````
ここからもし正しくHTTP通信できれば、getの戻り値として
PromiseのT、つまりAxiousResponseが戻ってくるのがわかる。

（以下AxiousResponse）
```ts
export interface AxiosResponse<T = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: any;
  config: AxiosRequestConfig;
  request?: any;
}
```
```ts
interface Error {
    name: string;
    message: string;
    stack?: string;
}
```

以上の流れから分かるように、axiousエラーをすると、Error　と　AxiosError　で構成させているのが分かる。

では今回のに当てはめていくと、

```ts
const handleSubmit = async(event : React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setFieldErrors({});
    try {
      const response = await axios.post('http://localhost:4000/signUp', formData);
      console.log("this is response of form" , response);
      console.log("response is received");
      setFormData({
        username : "",
        password : "",
        retypePassword : ""
      });
    } catch (error) {
//ここのエラーハンドリングについて考える。
//またフロントのエラーによる表示処理をしたいので、stateでerrorオブジェクトとして管理する
  catch (error) {
      if(axios.isAxiosError(error) && error.response){

        const serverErrors = error.response.data.errors;
        console.log("this is test" , serverErrors)
         // サーバーから返されたエラーを解析し、フィールドごとにエラーメッセージを設定
        if(Array.isArray(serverErrors)){
          const newFieldErrors : FieldError = {};
          serverErrors.forEach((err : {path : string; msg : string }) => {
            newFieldErrors[err.path] = err.msg;
          });
          setFieldErrors(newFieldErrors);
          console.error("Validation errors (newField): " , newFieldErrors); 
        }
        } else {
          console.error("error signing up : " , error);
        }
    }
  }
 ```

上記の分岐処理ではこのエラーがaxiousErrorであり（true) , レスポンスがnullでない場合にres.statusを表示させている。それはAxiosResponseインターフェースに合致するオブジェクトになるから。
 これで抜けがなくres.statusでエラーメッセージを返すことができる。それぞれ status , name , message だったり受け取れるので、使うことができる


<br>
<hr>

参考記事

https://qiita.com/yuta-katayama-23/items/5b8bf72236eec9cadf41