Внешний мониторинг исключений и аварийное восстановление

внешний интерфейс JavaScript
Внешний мониторинг исключений и аварийное восстановление

Исключением является непредвиденная ситуация в программе, влияющая на конечный результат презентации программы. Поэтому, когда мы разрабатываем, очень необходимо принимать меры предосторожности и проводить нештатный мониторинг для решения внезапных проблем.

Это может не только улучшить взаимодействие с пользователем, но и наши разработчики могут удаленно определить проблему, особенно на мобильном терминале.

Хотя для JS исключения обычно только прерывают выполнение текущей задачи и редко вызывают сбой.

Мониторинг аномалий — обязательный элемент полноценного клиентского решения.

Рядом с фронтом для нас, нужно делать ненормальности их

мониторинг исключений

Исключение выполнения JS

  • использоватьtry-catchКонкретные синтаксические ошибки и асинхронные ошибки не могут быть обнаружены, поэтому рекомендуется использовать мониторинг ошибок при предсказуемых обстоятельствах.
  • использоватьwindow.onerror, который сильнее, чем try-catch, но не может перехватывать исключения загрузки ресурсов или исключения интерфейса.Рекомендуется перехватывать непредвиденные ошибки.

Сочетание этих двух лучше

image.png

Собранное сообщение об ошибке печатается следующим образом

image.png

window.onerror = function (msg, url, row, col, error) {
    console.table({ msg, url, row, col, error: error.stack })
    let errorMsg = {
        type: 'javascript',
        // msg错误消息,error是错误对象,这里拿的是error.stack(异常信息)
        msg: error && error.stack ? error.stack || msg, 
        // 发生错误的行数
        row,
        // 列数,也就是第几个字符
        col,
        // 发生错误的页面地址
        url,
        // 发生错误的时间
        time: Date.now()
    }
    
    // 然后可以把这个 errorMsg 存到一个数组里,统一上报
    // 也可以直接上报
    Axios.post({ 'https://xxxx', errorMsg })
    
    // 如果return true,错误就不会抛到控制台
}

Есть два способа сообщить, один из них - использовать, как в приведенном выше коде.AJAX, будет междоменный, поэтому ему нужна серверная поддержка; другой — использоватьImageОбъект, это имеет то преимущество, что запрос изображения не является междоменным; обратите внимание на то, чтобы длина URL-адреса не превышала лимит. Следующие примеры не перечислены один за другим.

let url = 'https://xxx' + '错误信息'
new Image.src = url

Исключение при загрузке ресурсов

использоватьaddEventListener('error', callback, true)Захватите информацию об ошибке загрузки ресурсов на этапе захвата и сообщите об этом на сервер

addEventListener('error', e => {
    const targe = e.target
    if(target != window){
        //这里收集错误信息
        let errorMsg = {
            type: target.localName, // 错误来源名称。比如图片这里就是'img'
            url: target.src || target.href, //错误来源的链接
            // .... 还需要其他信息可以自己补充
        }
        // 把这个 errorMsg 存到一个数组里,然后统一上报
        // 或者直接上报
        Axios.post({ 'https://xxxx', errorMsg })
    }
}, true)

Обещание исключения

unhandledrejection

использоватьaddeventListener('unhandledrejection',callback)Поймать ошибки Promise. Однако количество строк не может быть захвачено.Когда время триггера отклонено, но не отклонено, это может произойти под окном или в Worker.

window.addEventListener("unhandledrejection", (e) => {
    console.log(e)
    let errorMsg = {
        type: 'promise',
        msg: e.reason.stack || e.reason
        // .....
    }
    Axios.post({ 'https://xxxx', errorMsg })
    
    // 如果return true,错误就不会抛到控制台
})
new Promise(() => {
    s
})

вот что распечатывает

image.png

rejectionhandled

Ошибка обещания была обработана, вызывает это

window.addEventListener("unhandledrejection", (e) => {
    console.log('错误了')
})
window.addEventListener("rejectionhandled", (e) => {
    console.log('错误已经处理了')
})

Исключение Vue

errorHandle

Обработчик, который Vue назначает для ошибок, не обнаруженных во время функций рендеринга компонентов и наблюдателей. Однако, как только этот метод обнаружит ошибку, ошибка не будет выведена на консоль.

Vue.config.errorHandler = (err, vm, info) => {
    // err 错误处理
    // vm vue实例
    // info 是特定于vue的错误信息,比如哪个生命周期勾子

    // 如果需要把错误抛到控制台,需要在这里加上这一行
    console.error(err)
}

warnHandle

Предупреждение Vue о назначении пользовательского обработчика. Однако это действительно только в среде разработки, а производственная среда будет игнорироваться сама по себе.

Vue.config.warnHandle = (msg, vm, trace){
    // trace 是组件层次结构
}

renderError

Когда функция рендеринга по умолчанию обнаруживает ошибку, предоставляется альтернатива для рендеринга вывода. Это было бы здорово использовать с горячей перезагрузкой

new Vue({
    render (h){
        throw new Error('oops')
    },
    renderError (h, err){
        return h('per',{ style: { color: red } }, err.stack)
    }
}).$mount('#app')

errorCaptured

Вызывается, когда какой-либо производный компонент перехватывает ошибку. Он может вернуть false, чтобы остановить распространение ошибки. В этом хуке можно изменить состояние компонента. Однако, если в шаблонах или функциях рендеринга есть условные операторы, при обнаружении ошибки эти условные операторы будут замкнуты и могут войти в бесконечный цикл рендеринга.

Vue.component('ErrorBoundary',{
    data: () => { ... }
    errorCaptured(err, vm, info){
        // err 错误信息  
        // vm 触发错误的组件实例 
        // info 错误捕获位置信息
        return false
    }
})

Реагировать на исключение

getDerivedStateFromError

У React также есть собственный метод отлова ошибок во всех дочерних компонентах.Этот жизненный цикл вызывается, когда дочерние компоненты выдают ошибки. Обратите внимание, что это вызывается на этапе рендеринга, поэтому побочные эффекты не допускаются.

class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props)
        this.state = { hasError: false }
    } 
    static getDerivedStateFromError(error) {
        // 更新 state 使下一次渲染可以显降级 UI
        return { hasError: true }
    }
}

componentDidCatch

Этот жизненный цикл также вызывается, когда компоненты-потомки выдают ошибки, но исключения из обработчиков событий и асинхронного кода не перехватываются. Он будет вызываться на этапе [commit], поэтому побочные эффекты разрешены.

class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props)
    } 
    componentDidCatch(error, info){
        // error 错误信息
        // info.componentStack 错误组件位置
    }
}

Фронтенд аварийное восстановление

Восстановление передних бедствий относится к различным причинам, связанным с внутренним интерфейсами (например, включение сервера от сети и т. Д.), Передняя страница все еще должна убедиться, что информация может завершить шоу.

Например, из интерфейса получаются такие данные, как баннер или список, что делать, если интерфейс не может быть получен?

LocalStorage

Во-первых, используйте LocalStorage

Когда интерфейс возвращается нормально, данные сохраняются в LocalStorage, путь к интерфейсу может использоваться как ключ, а возвращаемые данные могут использоваться как значение.

Затем снова запросите, если запрос не выполнен, прочитайте LocalStorage, отобразите последние данные и сообщите информацию об ошибке, чтобы получить время буферизации.

CDN

При этом копия статических данных должна быть скопирована и помещена в CDN для каждого обновления.

Когда запрос на интерфейс не удается, и в локальной табличке нет данных, перейдите к CDN для извлечения резервных статических данных

Service Worker

Если вы хотите сохранить не только данные интерфейса, но весь HTML вы можете использовать сервисный работник для автономного хранения

Использование перехвата запросов Service Worker, будь то для хранения данных интерфейса или для хранения файлов статических ресурсов страницы.

// 拦截所有请求事件 缓存中有请求的数据就直接用缓存,否则去请求数据 
self.addEventListener('fetch', e => { 
    // 查找request中被缓存命中的response 
    e.respondWith(caches.match(e.request).then( response => { 
        if (response) { 
            return response 
        } 
        console.log('fetch source') 
    })) 
})

Если вы сделаете все это хорошо, весь веб-сайт может полностью работать в автономном режиме, но проблема также очевидна, то есть на страницах с высокой своевременностью может возникнуть проблема, связанная с тем, что данные не могут обновляться синхронно (например, инвентарь продавца недостаточен). и отображение не соответствует)

Кроме того, необходимо обеспечить возможность обновления самой страницы интерфейса.Например, после того, как страница вышла из строя, бизнес-система должна выпустить новую версию для исправления и обновления.Необходимо убедиться, что ресурсы новая версия может полностью заменить онлайн-ресурсы старой версии.

Эпилог

Ставь лайк и поддержи, оставь аромат в руке и будь почетным

Спасибо за то, что вы здесь!