Рубрики
Без рубрики

Отчеты об ошибке в реальном времени в JavaScript

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

Автор оригинала: Christian Nwamba.

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

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

Эта статья объясняет практический подход к использованию толкателя, в реальном времени PUB/SUB Сервис, для мониторинга ошибок (особенно неожиданно), когда они бросаются.

Мы создадим приложение Basic Browser, которое имитирует приложение Real Life, бросая ошибку. Мы будем намеренно выбросить эти ошибки нажатием кнопки или два. План есть, когда эта ошибка бросается, настроен эта обработчик события глобального ошибки, который его обработчик отправит в качестве запроса на сервер через XHR.

Затем сервер будет использоваться триггеры Pusher, чтобы выделить события, которые произошла ошибка, поэтому все подключенные клиенты могут подписаться на событие. В нашем случае у нас просто один подключенный клиент, который отображает каждую ошибку как карты в реальном времени.

Это приводит нас к классификации нашего приложения в:

  1. Клиент : Это приложение для клиента, которое имеет тенденцию бросать ошибки. В нашем случае мы просто будем генерировать преднамеренные ошибки с помощью кнопки.
  2. Сервер : Клиент только что генерирует ошибки и уведомляет сервер. Затем сервер отвечает за регистрацию ошибок и отображения их на всех подключенных клиентах с использованием событий толкателя.

Ошибки клиента

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


We love errors!

...and promise to throw some in REALTIME

Ради простоты, тег головки не включен. Он просто импортирует базовый файл CSS, который вы можете найти в Demo CodePen в конце статьи. Ниже приведен скриншот результата:

Изображение клиентского приложения

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

Axios Внешний файл CDN внешний файл JS представляет собой утилитую библиотеку для создания HTTP-запросов. Нам нужно это отправить HTTP-запрос при возникновении ошибки. app.js Наш пользовательский файл JavaScript теперь мы рассмотрим его контент.

Прикрепление событий

Нам нужно прикрепить события как к кнопкам, так и для окно Отказ Прежде чем это сделать, давайте создадим функцию конструктора для приложения:

// app.js
(function() {
  // Constructor function
  function App (){
    // Grab all events
    this.buttons = document.querySelectorAll('button');
  }
  
}())

Теперь создайте метод, который прикладывает слушатель события к обеим кнопкам:

// ...
App.prototype.attachEvents = function() {
    // Button Events
    this.buttons.forEach((button, index) => {
      button.addEventListener('click', () => {
        if(index === 0) {
          // yet to be created
          // but throws error
          this.throwDefault()
        } else {
          // yet to be created
          // but throws another error
          this.throwSomeMore()
        }
      })
    })

    // Window error events
  }
// ...

Мы уже знаем, что делают события кнопки, но почему нам нужно прикрепить событие для окно объект? Браузеры позволяют ловить ошибки во всем мире, используя Ошибка . мероприятие. Следовательно, всякий раз, когда происходит ошибка в вашем приложении, это событие будет запущено. Это событие ошибки можно прикрепить к окно объект:

App.prototype.attachEvents = function() {
    // Button events

    // Window error event
    window.addEventListener('error', e => {
      // when an error occurs,
      // send the error information
      // to our yet to be created server
      this.sendPayloadToServer({
        lineno: e.lineno,
        colno: e.colno,
        filename: e.filename,
        message: e.error.message,
        stack: e.error.stack
      })
    })
  }

Ошибка бросания

rapdefault и Чуть чушь Являются ли методы, вызываемые, когда кнопки нажаты. Давайте создадим их и используем их, чтобы бросить ошибки:

App.prototype.throwDefault = function() {
 throw new Error('An error occurred...')
}

App.prototype.throwSomeMore = function() {
  throw new Error('...some more errors have occurred')
}

Консоль показывает, что ошибки выброшены:

Изображение ошибок броска клиентских приложений

Отправить ошибки на сервер

Помните, когда возникают ошибки, они обрабатываются Ошибка . Мероприятие на окно Отказ Обработчик событий отправляет эти ошибки в качестве полезной нагрузки на сервер, используя sendpayloadtOserver Отказ Давайте посмотрим, как выглядит функция:

App.prototype.sendPayloadToServer = function(e) {
  // send error to server endpoint
  axios.post('http://localhost:5000/report/error', e)
     .then(data => {
       console.log(data);
     })
 }

Ошибка полезной нагрузки отправляется на /Отчет/Ошибка Конечная точка, которую мы создадим во время разговора о сервере. Axios используется для создания этого запроса, позвонив пост Метод, который принимает URL и полезную нагрузку и возвращает обещание.

Предоставление сервера

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

Поскольку мы говорим JavaScript, давайте предоставим сервер с узлом, используя Экспресс генератор Отказ Чтобы сделать это, нам нужно установить генератор глобально, прежде чем генерировать приложение:

# Install express generator
# globally
npm install -g express-generator
# Generate an app called
# error-server with ejs as view template
express --view=ejs error-server

Следующее изображение показывает вывод генерации приложения New Express:

Шаблон генерации изображений

Что Экспресс делает за пределами объема этой статьи; Это рамки маршрутизации для узла, и вы можете узнать больше об этом на сайте.

Включение CORS.

Забывание вопросов CORS легко. Мы имеем дело с двумя разными приложениями, которые работают из разных доменов. Следовательно, нам нужно позволить серверу знать об этом, позволяя CORS. Это может быть сделано из файла ввода, app.js Прямо перед импортом маршрутов:

// ./app.js
//...
// CORS
app.all('/*', function(req, res, next) {
  // CORS headers
  res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain
  res.header('Access-Control-Allow-Methods', 'GET,POST');
  // Set custom headers for CORS
  res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
});

// Routes must come after
// enabling CORS
var index = require('./routes/index');
var report = require('./routes/report');

app.use('/', index);
app.use('/report/error', report);

Важно, чтобы вы разместили промежуточные программы CORS перед маршрутами.

Создание обработчика ошибок

/Пункт/Ошибка Маршрут, показанный выше еще не создан, но его обработчик импортируется. Это маршрут, который наше клиентское приложение отправляет почтовый запрос. Давайте создадим это:

// ./routes/report.js
const express = require('express');
const router = express.Router();

router.post('/', (req, res, next) => {
  // Emit a realtime pusher event
  res.send(req.body);
});

Прямо сейчас это не делает ничего больше, чем отправить нас, что мы отправили на него. Мы предпочли бы, чтобы он запускал мероприятие Pusher.

События толкателя

Pusher известен для шаблона PUB/SUB (события), который он представляет для создания решений в реальном времени. Этот шаблон легко работать, потому что разработчики (даже начинающие) используются для написания событий.

Событие Издательство является источником события и полезной нагрузки, в то время как Подписчик является потребителем события и полезной нагрузки. Пример объяснит это лучше:

// ./routes/report.js

// Import the Pusher
// JS SDK
const Pusher = require('pusher');

// Configure with the
// constructor function
const pusher = new Pusher({
  appId: 'APP-ID',
  key: 'APP-KEY',
  secret: 'APP-SECRET',
  cluster: 'CLUSTER',
  encrypted: true
});

/* Handle error by emitting realtime events */
router.post('/', (req, res, next) => {
  // emit an 'error' event 
  // via 'reports' channel,
  //  with the request body as payload
  pusher.trigger('reports', 'error', req.body);
  res.send(req.body);
});

module.exports = router;

Для работы, для работы, вам нужно установить толкатель SDK:

npm install --save pusher

Образцы кода показывают, как настроить Pusher, используя Толкатель Функция конструктора. Функция передается объект конфигурации с учетными данными, которые вы получаете при создании Приложение Pusher Отказ Не стесняйтесь принимать шаги в разделе Приложения внизу этой статьи, чтобы настроить учетную запись/приложение PUSHER, если у вас их уже нет.

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

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

Перечисление ошибок

Мы сгенерировали ошибки намеренно. Мы сообщаем о них с сервером, и сервер действует на него. Как мы узнаем, когда придут ошибки?

Примечание. Есть один маршрут, / , который мы не присутствовали. Этот маршрут просто делает EJS Вид шаблона:

// ./routes/index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

module.exports = router;

Изведомая страница может использоваться для отображения списка ошибок в реальном времени. Это то, как выглядит упрощенный HTML:


Error Log

Error message: something went wrong acd

Stack Trace: Lorem ipsum dolor sit amet,...

file.js

21:11

Шаблон содержит виджет карты, который скрыт по умолчанию с использованием CSS. Свойство отображения применяется с использованием Шаблон карты класс:

/* ./public/stylesheets/style.css */
.card-template {
 display: none
}

План есть, когда загрузка вступает, мы клонируем шаблон, удалите Шаблон карты Класс, обновите текстовое содержимое с значениями полезных нагрузок и добавьте к HTML.

Мы также импортируем Pusher SDK, потому что нам нужно слушать Ошибка . мероприятие.

app.js Файл отвечает за это:

// ./public/javascripts/app.js

(function(){
  function App () {
    // card template and cards parent
    this.cardTemplate = document.querySelector('.card-template');
    this.errorCards = document.querySelector('.error-cards');
  }
  
  // creates a card by cloning card template
  // and updates the card with data
  // from pusher subscription
  App.prototype.updateCard = function(data) {
    // clone template
    const card = this.cardTemplate.cloneNode(true);
    
    // update card contents and attributes
    card.classList.remove('card-template');
    card.querySelector('.error-card > h4').textContent = data.message;
    card.querySelector('.error-card > p').textContent = data.stack;
    card.querySelector('.error-details > h4 > a').textContent = data.filename;
    card.querySelector('.error-details > h4 > a').setAttribute('href', data.filename)
    card.querySelector('.error-details > p').textContent = `${data.lineno}:${data.colno}`;
   
    // append to parent
    this.errorCards.appendChild(card);
  }
  
  // sets up the app
  App.prototype.boot = function() {
    // allow pusher to log to your console
    // DO THIS ONLY IN DEV
    Pusher.logToConsole = true;
    
    // configure pusher with app key
    const pusher = new Pusher('', {
      cluster: 'CLUSTER',
      encrypted: true
    });
    
    // subscribe to 'reports' channel
    const channel = pusher.subscribe('reports');
    // bind to error events to receive payload
    channel.bind('error', (data) => {
      console.log('-- pusher --', data)
      // update cards
      this.updateCard(data);
    });
  }

  var app = new App();
  app.boot();
}())

Функция конструктора, Приложение , создается со ссылкой на шаблон карты и родитель карты (где мы приложим реальные карты).

Когда приложение загружено, мы сначала настройте толкатель с помощью ключа приложения. Экземпляр используется для подписки на Отчеты канал и связываться с Ошибка . мероприятие. привязывать Метод принимает обратный вызов, который находится в том месте, где UI обновляется с помощью UpdateCard Отказ

Это скриншот экрана листинга:

Список экрана

… и GIF, показывающий обновления в реальном времени

Demo Demo.

Заключение

Вы узнали лучший способ обрабатывать ошибки. Теперь вы можете предоставить своим клиентам поддержку, которую они заслуживают, незамедлительно отвечая на ошибки, которые они сталкиваются с использованием приложений.

Не стесняйтесь добраться до любого из ресурсов:

  1. Источник в Github
  2. Сервера демонстрация на Heroku
  3. Демо-демонстрация клиента на кодепене :

Оригинал опубликован в Блог Pusher Отказ

Приложение: Настройка учетной записи/приложения PUSHER

  1. Зарегистрируйтесь Для бесплатной учетной записи Pusher

  2. Создайте новое приложение, выбрав Приложения на боковой панели и нажав Создать новый Кнопка на нижней части боковой панели:

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