/**
 * API异常模块
 * @date 2022-03
 * @author 何华东
 */

import { AxiosError, AxiosResponse } from 'axios';

/**
 * 接口异常
 */
export class ApiError {
    /**
     * 接口分类名，例如：统一接口、非标接口、杭停接口
     */
    apiCategory: string;

    /**
     * 接口描述，例如：2.0.1获取平台配置信息
     */
    apiDesc?: string;

    /**
     * 错误信息
     */
    message?: string;

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

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

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

    /**
     * axiosError.code
     * 
     * ECONNABORTED 为请求超时时
     */
    code?: string;

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

    /**
     * 响应
     */
    apiResponse?: any;

    toString() {
        return `${this.apiCategory}${this.apiDesc ? '/' + this.apiDesc : ''} 调用失败,错误信息:${this.message || ''},请求地址:${this.requestUrl},请求头:${JSON.stringify(this.requesHeaders)},请求数据:${JSON.stringify(this.requestData)},http状态码:${this.statusCode},返回值:${JSON.stringify(this.apiResponse)}`;
    }
}

/**
 * 从axiosError生成一个ApiError异常对象
 * @param apiCategory api分类名，例如：统一接口、非标接口
 */
function generateApiErrorFromAxiosError(axiosError: AxiosError, apiCategory: string) {
    let apiError = new ApiError();

    apiError.apiCategory = apiCategory;
    apiError.apiDesc = axiosError.config['apiDesc'];
    apiError.message = axiosError.message;
    apiError.requestUrl = axiosError.config.url?.startsWith('http') ? axiosError.config.url : (axiosError.config.baseURL + (axiosError.config.url || ''));
    apiError.requesHeaders = axiosError.config.headers;
    apiError.requestData = axiosError.config.data;
    apiError.code = axiosError.code;
    apiError.statusCode = axiosError.response?.status;
    apiError.apiResponse = axiosError.response?.data;

    return apiError;
}

/**
 * 从axiosResponse生成一个ApiError异常对象
 * @param apiCategory api分类名，例如：统一接口、非标接口
 */
function generateApiErrorFromAxiosResponse(axiosResponse: AxiosResponse, apiCategory: string, message?: string) {
    let apiError = new ApiError();

    apiError.apiCategory = apiCategory;
    apiError.message = message;
    apiError.apiDesc = axiosResponse.config['apiDesc'];
    apiError.requestUrl = axiosResponse.config.url?.startsWith('http') ? axiosResponse.config.url : (axiosResponse.config.baseURL + (axiosResponse.config.url || ''));
    apiError.requesHeaders = axiosResponse.config.headers;
    apiError.requestData = axiosResponse.config.data;
    apiError.statusCode = axiosResponse.status;
    apiError.apiResponse = axiosResponse.data;

    return apiError;
}

/**
 * 从AxiosError抛出ApiError异常
 * @param apiCategory 接口分类名
 */
export function throwApiErrorFromAxiosError(axiosError: AxiosError, apiCategory: string) {
    throw generateApiErrorFromAxiosError(axiosError, apiCategory);
}

/**
 * 从AxiosResponse抛出ApiError异常
 * @param message 错误信息
 * @param apiCategory 接口分类名
 */
export function throwApiErrorFromAxiosResponse(axiosResponse: AxiosResponse, apiCategory: string, message?: string,) {
    throw generateApiErrorFromAxiosResponse(axiosResponse, apiCategory, message);
}