# All files / core errorId.ts

54.9% Statements 28/51
35% Branches 7/20
50% Functions 4/8
55.1% Lines 27/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    1072x

    2x

    2x

    10x
    10x

    4x
    4x

    6x
    6x

    10x
    10x
    3x

    7x
    2x

    5x

    7x

    2x
    17x

    2x
    11x

    10x
    10x
    10x
    504x
    504x
    504x

    10x

     import { ERRORTYPES, EVENTTYPES } from '../common/common'
    import { ReportDataType } from '../types/transportData'
    const allErrorNumber: unknown = {}
    /**
     * error合并规则
     * @param data
     */
    export default function createErrorId(data: ReportDataType): number | null {
      let id: any
      const originUrl = getRealPageOrigin(data.url)
      switch (data.type) {
        case ERRORTYPES.FETCH_ERROR:
          id = data.type + data.request.method + data.response.status + getRealPath(data.request.url) + originUrl
          break
        case ERRORTYPES.JAVASCRIPT_ERROR:
        case ERRORTYPES.VUE_ERROR:
        case ERRORTYPES.REACT_ERROR:
          id = data.type + data.name + data.message + originUrl
          break
        case ERRORTYPES.BUSINESS_ERROR:
        case ERRORTYPES.LOG_ERROR:
          id = data.customTag + data.type + data.name + originUrl
          break
        case ERRORTYPES.PROMISE_ERROR:
          id = generatePromiseErrorId(data, originUrl)
          break
        default:
          id = data.type + data.message + originUrl
          break
      }
      id = hashCode(id)
      if (allErrorNumber[id] > 1) {
        return null
      }
      if (typeof allErrorNumber[id] === 'number') {
        allErrorNumber[id]++
      } else {
        allErrorNumber[id] = 1
      }

      return id
    }

    function generatePromiseErrorId(data: ReportDataType, originUrl: string) {
      const locationUrl = getRealPath(data.url)
      if (data.name === EVENTTYPES.UNHANDLEDREJECTION) {
        return data.type + objectOrder(data.message) + originUrl
      }
      return data.type + data.name + objectOrder(data.message) + locationUrl
    }

    /**
     * 排序对象键值对
     * ../param reason promise.reject
     */
    function objectOrder(reason: any) {
      const sortFn = (obj: any) => {
        return Object.keys(obj)
          .sort()
          .reduce((total, key) => {
            if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
              total[key] = sortFn(obj[key])
            } else {
              total[key] = obj[key]
            }
            return total
          }, {})
      }
      try {
        if (/\{.*\}/.test(reason)) {
          let obj = JSON.parse(reason)
          obj = sortFn(obj)
          return JSON.stringify(obj)
        }
      } catch (error) {
        return reason
      }
    }

    /**
     * http://.../project?id=1#a => http://.../project
     * http://.../id/123=> http://.../id/{param}
     *
     * @param url
     */
    export function getRealPath(url: string): string {
      return url.replace(/[\?#].*$/, '').replace(/\/\d+([\/]*$)/, '{param}$1')
    }
    /**
     * http://a.b.com/#/project?id=1 => a.b.com
     * @param url
     */
    export function getRealPageOrigin(url: string): string {
      return getRealPath(url.replace(/(\S+)(\/#\/)(\S*)/, `$1`).replace(/(\S*)(\/\/)(\S+)/, '$3'))
    }

    function hashCode(str: string): number {
      let hash = 0
      Iif (str.length == 0) return hash
      for (let i = 0; i < str.length; i++) {
        const char = str.charCodeAt(i)
        hash = (hash << 5) - hash + char
        hash = hash & hash
      }
      return hash
    }