/**
 * axios帮助模块
 * @date 2022-03
 * @author 何华东
 */

import { AxiosError, AxiosResponse } from 'axios';

/**
 * API异常类
 * 
 * axios自带的异常对象AxiosError属性较多，所以自定义一个简化的异常对象替代AxiosError进行使用
 * 
 * axios一般用来请求api，所以将该异常命名为ApiError
 */
export class ApiError extends Error {
    constructor() {
        super();
        this.name = 'ApiError';
    }

    /**
     * 请求地址
     */
    requestUrl: string;

    /**
     * 请求头
     */
    requestHeaders?: any;

    /**
     * 请求数据
     */
    requestData?: any;

    /**
     * 错误码，请求超时时code='ECONNABORTED'
     * 
     * 对应AxiosError.code
     */
    code?: string;

    /**
     * http状态码，例如：200、500、404
     * 
     * 对应AxiosError.statusCode
     */
    statusCode?: any;

    /**
     * 请求返回值，即使请求发生异常(404,500)，也可能会有返回值
     * 
     * 对应AxiosError.response.data
     */
    apiResponse?: any;
}

/**
 * 从指定的AxiosError异常对象生成一个ApiError对象
 * @param error 指定的AxiosError异常对象
 * @returns 
 */
export function generateApiErrorFromAxiosError(error: AxiosError) {
    let apiError = new ApiError();

    apiError.name = error.name;
    apiError.message = error.message;
    apiError.requestUrl = error.config.url?.startsWith('http') ? error.config.url : (error.config.baseURL + (error.config.url || ''));
    apiError.requestHeaders = error.config.headers;
    apiError.requestData = error.config.data;
    apiError.code = error.code;
    apiError.statusCode = error.response?.status;
    apiError.apiResponse = error.response?.data;

    return apiError;
}

/**
 * 从指定的AxiosResponse对象生成一个ApiError对象
 * 
 * api可能返回错误信息，也可以理解为api异常
 * @param axiosResponse 指定的AxiosResponse对象
 * @param message 错误信息
 * @returns 
 */
export function generateApiErrorFromAxiosResponse(axiosResponse: AxiosResponse, message?: string) {
    let apiError = new ApiError();

    apiError.message = message;
    apiError.requestUrl = axiosResponse.config.url?.startsWith('http') ? axiosResponse.config.url : (axiosResponse.config.baseURL + (axiosResponse.config.url || ''));
    apiError.requestHeaders = axiosResponse.config.headers;
    apiError.requestData = axiosResponse.config.data;
    apiError.apiResponse = axiosResponse.data;

    return apiError;
}