Как найти ошибку в коде страницы

Как проверить CSS и HTML-код на валидность и зачем это нужно.

В статье:

  1. Что такое валидность кода

  2. Чем ошибки в HTML грозят сайту

  3. Как проверить код на валидность

  4. HTML и CSS валидаторы — онлайн-сервисы для проверки кода

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

Что такое валидность кода

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

Для этого есть специальные стандарты: если им следовать, страницу будут корректно распознавать все браузеры и гаджеты. Такой стандарт разработал Консорциумом всемирной паутины — W3C (The World Wide Web Consortium). HTML-код, который ему соответствует, называют валидным.

Валидность также касается файлов стилей — CSS. Если в CSS есть ошибки, визуальное отображение элементов может нарушиться.

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

Чем ошибки в HTML грозят сайту

Типичные ошибки кода — незакрытые или дублированные элементы, неправильные атрибуты или их отсутствие, отсутствие кодировки UTF-8 или указания типа документа.

Какие проблемы могут возникнуть из-за ошибок в HTML-коде

  • страницы загружаются медленно;
  • сайт некорректно отображается на разных устройствах или в браузерах;
  • посетители видят не весь контент;
  • программист не замечает скрытую рекламу и вредоносный код.

Как валидность кода влияет на SEO

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

Почитать по теме:
Главное о микроразметке: подборка знаний для веб-мастеров

Представитель Google Джон Мюллер говорил о валидности кода:

«Мы упомянули использование правильного HTML. Является ли фактором ранжирования валидность HTML стандарту W3C?

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

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

Итак, критические ошибки в HTML мешают

  • сканированию сайта поисковыми ботами;
  • определению структурированной разметки на странице;
  • рендерингу на мобильных устройствах и кроссбраузерности.

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

Как проверить код на валидность

Не нужно вычитывать код и считать символы — для этого есть сервисы и инструменты проверки валидности HTML онлайн.

Что они проверяют:

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

    .

  • DTD (Document Type Definition)
    Соответствие кода указанному DTD, правильность названий тегов, вложенности, атрибутов. Наличие пользовательских тегов и атрибутов — то, чего нет в DTD, но есть в коде.

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

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

Почитать по теме:
Уменьшить вес сайта с помощью gzip, brotli, минификации и других способов

Поэтому анализируйте предложения сервисов по исправлениям и ориентируйтесь на здравый смысл.

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

HTML и CSS валидаторы — онлайн-сервисы для проверки кода

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

Валидатор от W3C

Англоязычный сервис, онлайн проверяет соответствие HTML стандартам: можно проверить код по URL, залить файл или вставить код в окошко.

Инструмент покажет список ошибок и предупреждений с пояснениями — описанием ошибки и ее типом, а также укажет номер строки, в которой нужно что-то исправить. Цветом отмечены типы предупреждений и строчки с кодом.

проверка кода html на валидность

Фрагмент примера проверки

Валидатор CSS от W3C

Инструмент от W3C для проверки CSS, есть русский язык. Работает по такому же принципу, анализирует стили на предмет ошибок и предупреждений. Первым идет блок ошибок, предупреждения собраны ниже отдельно.

как проверить валидность CSS

Проверка CSS

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

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

HTML Validator is a free online developer tool to validate HTML code against the W3C standards as known as HTML linter instantly. Supports partial HTML code validation.

You can either browse an HTML file, fetch HTML code from a URL, or paste HTML code manually, and then click the validate button. The results will be displayed accordingly when the process is done.

Basically, there are two types of result messages: warning and error

Warning — A suggestion to fix your HTML code. For instance, an HTML attribute that can be omitted.

Error — An error in your HTML code that’s against the W3C standards. You’re encouraged to fix it.

Each message comes with a line number and excerpt code indicating where a warning or an error is located.

Optionally, you can partially validate HTML code by enabling the fragment option so that the HTML code will be treated as part of an HTML document instead of a full one.

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    HTML5 is easy to understand and it’s not compiled into different forms before the browser displays it.

    In any code, 2 types of errors are possible:

    1. Syntax error: Incorrect syntax leading to compile time error in other languages.HTML have no affect of syntax error.
    2. Logical error: Syntax is correct but output is unexpected because of wrong logic.

    In HTML we never encounter syntax errors because the browser parses HTML permissively, which means that the page is displayed even if there are any syntax errors. Browsers have some built-in rules to display incorrect HTML. Therefore there would always be some output, even if it is not what is expected.

    The way that browsers parse HTML is a lot more permissive than how other programming languages are run, which leads to both good (content gets displayed) and bad scenarios (content is displayed in an unexpected manner).

    In the below example, there are some syntax errors like incomplete p tag, incomplete h1 tag, but still, it displays some of the content in an expected way. In this case, the initial p tag and h1 tag but the next p tag is displayed as h1. These scenarios are easy to identify and avoid in small codes but when the length of code increases, it will be complex to debug code.

    Example:

    HTML

    <!DOCTYPE html>

    <html>

    <head>

        <title>HTML errors</title>

    </head>

    <body>

        <h1>HTML errors</h1>

        <p>unclosed paragraph tag 

        <h1>its displaying the way it is intended

        <p>but it may lead to next unexpected thing

    </body>

    </html>

    Output:

    Validating our HTML: In order to make sure your html code is error free is by using html validation service by w3c. This site takes html as input and returns the errors in html document. You can provide html by providing link to html document, uploading html file or directly pasting html there.

    W3C interface

    Example: Let’s try by directly pasting html. Here is the result for the code given above. The errors in the HTML are highlighted, so now we can make changes accordingly in html and make it error free.

    Errors

    The error free HTML is shown below.

    HTML

    <!DOCTYPE html>

    <html>

    <head>

        <title>Page Title</title>

    </head>

    <body>

        <h2>Welcome To GFG</h2>

        <p>Default code has been loaded into the Editor.</p>

    </body>

    </html>

    Last Updated :
    31 Oct, 2021

    Like Article

    Save Article

    В этой статье я рассмотрю вопрос выявления и обработки ошибок, возникающих на фронтенде (браузер или web-view).

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

    1. Средства языка JavaScript

    Блоки try/catch

    Функции, которые могут выполниться с ошибкой, оборачивают в блоки try/catch. Сначала программа пытается выполнить код в блоке try. Если по каким-то причинам выполнение кода сломалось, программа переходит в блок catch, где доступны три параметра:

    • name — стандартизированное имя ошибки;
    • message — сообщение о деталях ошибки;
    • stack — текущий стек вызова, в котором произошла ошибка.

    То есть:

    try {
    
       callFunc();
    
    } catch (e) {
    
       console.log(e.name) // ReferenceError
    
       console.log(e.message) // callFunc is not defined
    
       console.log(e.stack) // ReferenceError: callFunc is not defined at window.onload
    
    }

    Для разработчика главное то, что программа сможет продолжить выполнение после блока catch. Таким образом, взаимодействие с пользователем не прервется.

    С помощью блока try/catch также можно вызывать собственные ошибки, например при проверке данных:

    const user = {
    
      name : «Mike»
    
    };
    
    try {
    
       if (!user.age) throw new SyntaxError(«User age is absent!»);
    
    } catch (e) {
    
       console.log(e.name) // SyntaxError
    
       console.log(e.message) // User age is absent!
    
       console.log(e.stack) // SyntaxError: User age is absent! at window.onload
    
    }

    Наконец, можно расширить эту инструкцию еще одним блоком — finally, который выполняется всегда: и в случае, если в try не было ошибки, и в случае, если управление перешло в блок catch:

    try {
    
       callFunc();
    
    } catch (e) {
    
       console.log(e)
    
    } finally {
    
       ...
    
    }

    Иногда используют инструкцию try/finally (без catch), чтобы была возможность продолжать использование кода без обработки конкретных ошибок.

    Событие window.onerror

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

    У глобального объекта window существует событие onerror (использовать его надо аккуратно: в разных браузерах реализация может отличаться!):

    window.onerror = function(message, url, line, col, error) {
    
       console.log(`${message}n В ${line}:${col} на ${url}`);
    
    };

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

    Однако полная информация доступна только для скриптов, которые были загружены с того же домена. Если сломанный скрипт загружен с другого домена, window.onerror сработает, однако подробностей ошибки не будет.

    Компоненты фреймворков

    Некоторые JS-фреймворки (React, Vue) предлагают собственные решения по обработке ошибок. Например, React сможет отрисовать специальную верстку на месте блока, в котором произошла ошибка:

    class ErrorBoundary extends React.Component {
    
       constructor(props) {
    
           super(props);
    
           this.state = { hasError: false };
    
       }
    
       static getDerivedStateFromError(error) {
    
           // Обновить состояние с тем, чтобы следующий рендер показал запасной UI.
    
           return { hasError: true };
    
       }
    
       componentDidCatch(error, errorInfo) {
    
           // Можно также сохранить информацию об ошибке в соответствующую службу журнала ошибок
    
           logErrorToMyService(error, errorInfo);
    
       }
    
       render() {
    
           if (this.state.hasError) {
    
               // Можно отрендерить запасной UI произвольного вида
    
               return <h1>Что-то пошло не так.</h1>;
    
           }
    
           return this.props.children;
    
       }
    
    }
    
    <ErrorBoundary>
    
       <MyWidget />
    
    </ErrorBoundary>

    Фактически, компонент React оборачивается специальным компонентом, который обрабатывает ошибки. Это напоминает оборачивание функций с помощью конструкции try/catch.

    2. Средства сборки проекта

    Современные JS-скрипты, как правило, делаются транспилируемыми. То есть разработка ведется с использованием последних стандартов ES. А затем код разработчика с помощью сборщика проектов (такого как Webpack) преобразуется в код, который будет гарантированно работать в выбранном числе браузеров.

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

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

    3. Тестирование

    Еще один способ не допустить ошибок в коде – тестировать его. Во фронтенде есть инструменты для эффективного использования юнит-тестов. Обычно используют фреймворки, такие как Jest, Karma, Mocha, Jasmine. Вместе с тестовыми фреймворками часто используют расширения, такие как Enzyme, React Testing Library, Sinon и другие, позволяющие обогатить тесты с помощью мокирования, функций-шпионов и других инструментов.

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

    const func = (data) => {
    
       return JSON.parse(data)
    
    }
    
    func('{«a»:1}')
    

    Однако он сломается, если подать ему неверное значение:

    func() // Uncaught SyntaxError: Unexpected token u in JSON at position 0.

    Этот код тоже проходит валидацию при сборке:

    const obj = {
    
       outer : {
    
           last : 9
    
       }
    
    }
    
    if (obj.outer.inner.last) {
    
       console.log(«SUCCESS»)
    
    }

    Однако он также сломается во время исполнения. После тестирования разработчик наверняка сделает дополнительные проверки:

    if (obj.outer?.inner?.last) {
    
       console.log(«SUCCESS»)
    
    }

    Часто подобные ошибки возникают при получение данных от сервера (например AJAX-запросом) с их последующим разбором. Тестирование кода позволяет выявить и заранее устранить случаи, когда код может сломаться во время исполнения в браузере клиента.

    4. Логирование

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

    Смысл простой: на каждое событие window.onerror или в каждый переход исполнения кода в блок catch выполняется простой AJAX-запрос на специально выделенный адрес сервера, в тело которого кладется информация об ошибке. Далее потребуется инструмент, который быстро оповестит техподдержку и разработчиков о наличии новых ошибок и позволит эффективно работать с ними. Самый популярный из таких инструментов для фронтенда — Sentry.

    Система логирования Sentry позволяет собирать, группировать, представлять ошибки в реальном времени. Есть сборки для разных языков, в том числе JavaScript. Проект предоставляет платный доступ с расширенными возможностями для бизнеса, однако можно попробовать его основные возможности на бесплатном тестовом аккаунте.

    Подключать Sentry можно как непосредственно в HTML-файле, так и в компонентах, выполненных на одном из популярных фреймворков: React, Vue, Angular, Ember и других.

    Для подключения возможностей логирования прямо в браузере в секции загружаем скрипт:

    <script
    
       src=«https://browser.sentry-cdn.com/5.13.0/bundle.min.js»
    
       integrity=«sha384-ePH2Cp6F+/PJbfhDWeQuXujAbpil3zowccx6grtsxOals4qYqJzCjeIa7W2UqunJ»
    
       crossorigin="anonymous"></script>

    Далее в коде JS инициализируем:

    Sentry.init({
    
       dsn: 'https://<your account key here>@sentry.io/<your project id here>'
    
    });

    Всё. Если и когда в коде ниже этой строчки произойдет ошибка, Sentry выполнит ее логирование. Логи будут записаны даже тогда, когда ошибка произошла по вине скриптов с других доменов:

    Sentry имеет широкие возможности по анализу массива сообщений об ошибках и настройке уведомлений. Также возможна группировка логов ошибок по релизам вашего продукта:

    Sentry.init({
    
       dsn: 'https://<your account key here>@sentry.io/<your project id here>',
    
       release: '2020.03.06.1'
    
    });

    С помощью Sentry в статистику можно передать контекст ошибки, например, информацию о клиенте, fingerprint, уровень ошибки (fatal, error, warning, info, debug), проставить теги.

    Есть возможность записывать в статистику пользовательские события. Например, можно поставить на отслеживание изменение размеров окна браузера или совершение AJAX-запроса. Также у Sentry есть собственный виджет с окном обратной связи, которое можно показать пользователю при ошибке. Это даст дополнительную информацию для расследования обстоятельств возникновения ошибки.

    Для развертывания Sentry вместе с фреймворками достаточно просто установить пакет и подключить:

    # Using yarn
    
    yarn add @sentry/browser
    
    # Using npm
    
    npm install @sentry/browser

    Делаем инициализацию в главном скрипте проекта (для React и Angular):

    import * as Sentry from «@sentry/browser»;
    
    Sentry.init({ dsn: 'https://<your account key here>@sentry.io/<your project id here>' });

    Для Vue и Ember передаем еще одну обязательную строку конфигурации:

    # Vue
    
    Sentry.init({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
       integrations: [new Integrations.Vue({Vue, attachProps: true})],
    
    });
    
    # Ember
    
    Sentry.init({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
       integrations: [new Integrations.Ember()]
    
    });

    Пакет integrations устанавливается отдельно:

    # Using yarn
    
    yarn add @sentry/integrations
    
    # Using npm
    
    npm install @sentry/integrations

    Для предотвращения конфликтов и дублирования информации при подключении нескольких скриптов в одном проекте Sentry позволяет создавать отдельного клиента для каждой инициализации логирования:

    import { BrowserClient } from «@sentry/browser»;
    
    const client = new BrowserClient({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
    });
    
    client.captureException(new Error('example'));

    На сайте проекта есть подробная документация с примерами использования: https://docs.sentry.io.

    Статья подготовлена при поддержке облачной платформы Mail.ru Cloud Solutions.

    Что еще почитать по теме:

    1. Переиспользуемые компоненты React: как перестать писать одно и то же.
    2. Как избежать ошибок при разработке на React.
    3. Наш телеграм-канал с новостями о цифровой трансформации.

    Недавно мы рассказали о том, как начать писать программы на JavaScript:

    • что такое HTML и JavaScript;
    • из чего состоят скрипты;
    • как и где их выполнять и куда вставлять;
    • где искать готовые решения и что с ними потом делать;
    • как работать с разными элементами и обрабатывать нажатия клавиш.

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

    Что такое отладка

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

    Варварская отладка

    Самый примитивный вариант отладки — добавить в код на JavaScript метод console.log(), поместив в скобки нужные данные для отладки. Console.log() — это просто способ вывести в консоль какой-нибудь текст. 

    Например, внутри функции можно сказать: console.log(‘Вызвана такая-то функция’) — и в нужный момент мы увидим, что функция вызвалась (или нет). 

    Минус этого подхода в том, что в коде появляется много отладочного мусора. А ещё, если мы не предусмотрели логирование для какой-то функции, то мы не поймаем в ней ошибку. 

    К счастью, помимо console.log() человечество изобрело много удобных инструментов отладки. 

    Что нужно для отладки

    Для несложных проектов на JavaScript проще всего использовать встроенный отладчик в браузере Google Chrome. Единственное ограничение — он работает только с файлами скриптов, а не со встроенным в страницу кодом. Это значит, что если код скрипта находится внутри HTML-файла внутри тега <script>, то отладка не сработает.

    Чтобы открыть панель отладки в Chrome, нажимаем ⌘+⌥+I и переходим на вкладку Sources (Источники):

    Как поймать баг в коде: отладка в браузере

    Validating our HTML: In order to make sure your html code is error free is by using html validation service by w3c. This site takes html as input and returns the errors in html document. You can provide html by providing link to html document, uploading html file or directly pasting html there.

    W3C interface

    Example: Let’s try by directly pasting html. Here is the result for the code given above. The errors in the HTML are highlighted, so now we can make changes accordingly in html and make it error free.

    Errors

    The error free HTML is shown below.

    HTML

    <!DOCTYPE html>

    <html>

    <head>

        <title>Page Title</title>

    </head>

    <body>

        <h2>Welcome To GFG</h2>

        <p>Default code has been loaded into the Editor.</p>

    </body>

    </html>

    Last Updated :
    31 Oct, 2021

    Like Article

    Save Article

    В этой статье я рассмотрю вопрос выявления и обработки ошибок, возникающих на фронтенде (браузер или web-view).

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

    1. Средства языка JavaScript

    Блоки try/catch

    Функции, которые могут выполниться с ошибкой, оборачивают в блоки try/catch. Сначала программа пытается выполнить код в блоке try. Если по каким-то причинам выполнение кода сломалось, программа переходит в блок catch, где доступны три параметра:

    • name — стандартизированное имя ошибки;
    • message — сообщение о деталях ошибки;
    • stack — текущий стек вызова, в котором произошла ошибка.

    То есть:

    try {
    
       callFunc();
    
    } catch (e) {
    
       console.log(e.name) // ReferenceError
    
       console.log(e.message) // callFunc is not defined
    
       console.log(e.stack) // ReferenceError: callFunc is not defined at window.onload
    
    }

    Для разработчика главное то, что программа сможет продолжить выполнение после блока catch. Таким образом, взаимодействие с пользователем не прервется.

    С помощью блока try/catch также можно вызывать собственные ошибки, например при проверке данных:

    const user = {
    
      name : «Mike»
    
    };
    
    try {
    
       if (!user.age) throw new SyntaxError(«User age is absent!»);
    
    } catch (e) {
    
       console.log(e.name) // SyntaxError
    
       console.log(e.message) // User age is absent!
    
       console.log(e.stack) // SyntaxError: User age is absent! at window.onload
    
    }

    Наконец, можно расширить эту инструкцию еще одним блоком — finally, который выполняется всегда: и в случае, если в try не было ошибки, и в случае, если управление перешло в блок catch:

    try {
    
       callFunc();
    
    } catch (e) {
    
       console.log(e)
    
    } finally {
    
       ...
    
    }

    Иногда используют инструкцию try/finally (без catch), чтобы была возможность продолжать использование кода без обработки конкретных ошибок.

    Событие window.onerror

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

    У глобального объекта window существует событие onerror (использовать его надо аккуратно: в разных браузерах реализация может отличаться!):

    window.onerror = function(message, url, line, col, error) {
    
       console.log(`${message}n В ${line}:${col} на ${url}`);
    
    };

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

    Однако полная информация доступна только для скриптов, которые были загружены с того же домена. Если сломанный скрипт загружен с другого домена, window.onerror сработает, однако подробностей ошибки не будет.

    Компоненты фреймворков

    Некоторые JS-фреймворки (React, Vue) предлагают собственные решения по обработке ошибок. Например, React сможет отрисовать специальную верстку на месте блока, в котором произошла ошибка:

    class ErrorBoundary extends React.Component {
    
       constructor(props) {
    
           super(props);
    
           this.state = { hasError: false };
    
       }
    
       static getDerivedStateFromError(error) {
    
           // Обновить состояние с тем, чтобы следующий рендер показал запасной UI.
    
           return { hasError: true };
    
       }
    
       componentDidCatch(error, errorInfo) {
    
           // Можно также сохранить информацию об ошибке в соответствующую службу журнала ошибок
    
           logErrorToMyService(error, errorInfo);
    
       }
    
       render() {
    
           if (this.state.hasError) {
    
               // Можно отрендерить запасной UI произвольного вида
    
               return <h1>Что-то пошло не так.</h1>;
    
           }
    
           return this.props.children;
    
       }
    
    }
    
    <ErrorBoundary>
    
       <MyWidget />
    
    </ErrorBoundary>

    Фактически, компонент React оборачивается специальным компонентом, который обрабатывает ошибки. Это напоминает оборачивание функций с помощью конструкции try/catch.

    2. Средства сборки проекта

    Современные JS-скрипты, как правило, делаются транспилируемыми. То есть разработка ведется с использованием последних стандартов ES. А затем код разработчика с помощью сборщика проектов (такого как Webpack) преобразуется в код, который будет гарантированно работать в выбранном числе браузеров.

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

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

    3. Тестирование

    Еще один способ не допустить ошибок в коде – тестировать его. Во фронтенде есть инструменты для эффективного использования юнит-тестов. Обычно используют фреймворки, такие как Jest, Karma, Mocha, Jasmine. Вместе с тестовыми фреймворками часто используют расширения, такие как Enzyme, React Testing Library, Sinon и другие, позволяющие обогатить тесты с помощью мокирования, функций-шпионов и других инструментов.

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

    const func = (data) => {
    
       return JSON.parse(data)
    
    }
    
    func('{«a»:1}')
    

    Однако он сломается, если подать ему неверное значение:

    func() // Uncaught SyntaxError: Unexpected token u in JSON at position 0.

    Этот код тоже проходит валидацию при сборке:

    const obj = {
    
       outer : {
    
           last : 9
    
       }
    
    }
    
    if (obj.outer.inner.last) {
    
       console.log(«SUCCESS»)
    
    }

    Однако он также сломается во время исполнения. После тестирования разработчик наверняка сделает дополнительные проверки:

    if (obj.outer?.inner?.last) {
    
       console.log(«SUCCESS»)
    
    }

    Часто подобные ошибки возникают при получение данных от сервера (например AJAX-запросом) с их последующим разбором. Тестирование кода позволяет выявить и заранее устранить случаи, когда код может сломаться во время исполнения в браузере клиента.

    4. Логирование

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

    Смысл простой: на каждое событие window.onerror или в каждый переход исполнения кода в блок catch выполняется простой AJAX-запрос на специально выделенный адрес сервера, в тело которого кладется информация об ошибке. Далее потребуется инструмент, который быстро оповестит техподдержку и разработчиков о наличии новых ошибок и позволит эффективно работать с ними. Самый популярный из таких инструментов для фронтенда — Sentry.

    Система логирования Sentry позволяет собирать, группировать, представлять ошибки в реальном времени. Есть сборки для разных языков, в том числе JavaScript. Проект предоставляет платный доступ с расширенными возможностями для бизнеса, однако можно попробовать его основные возможности на бесплатном тестовом аккаунте.

    Подключать Sentry можно как непосредственно в HTML-файле, так и в компонентах, выполненных на одном из популярных фреймворков: React, Vue, Angular, Ember и других.

    Для подключения возможностей логирования прямо в браузере в секции загружаем скрипт:

    <script
    
       src=«https://browser.sentry-cdn.com/5.13.0/bundle.min.js»
    
       integrity=«sha384-ePH2Cp6F+/PJbfhDWeQuXujAbpil3zowccx6grtsxOals4qYqJzCjeIa7W2UqunJ»
    
       crossorigin="anonymous"></script>

    Далее в коде JS инициализируем:

    Sentry.init({
    
       dsn: 'https://<your account key here>@sentry.io/<your project id here>'
    
    });

    Всё. Если и когда в коде ниже этой строчки произойдет ошибка, Sentry выполнит ее логирование. Логи будут записаны даже тогда, когда ошибка произошла по вине скриптов с других доменов:

    Sentry имеет широкие возможности по анализу массива сообщений об ошибках и настройке уведомлений. Также возможна группировка логов ошибок по релизам вашего продукта:

    Sentry.init({
    
       dsn: 'https://<your account key here>@sentry.io/<your project id here>',
    
       release: '2020.03.06.1'
    
    });

    С помощью Sentry в статистику можно передать контекст ошибки, например, информацию о клиенте, fingerprint, уровень ошибки (fatal, error, warning, info, debug), проставить теги.

    Есть возможность записывать в статистику пользовательские события. Например, можно поставить на отслеживание изменение размеров окна браузера или совершение AJAX-запроса. Также у Sentry есть собственный виджет с окном обратной связи, которое можно показать пользователю при ошибке. Это даст дополнительную информацию для расследования обстоятельств возникновения ошибки.

    Для развертывания Sentry вместе с фреймворками достаточно просто установить пакет и подключить:

    # Using yarn
    
    yarn add @sentry/browser
    
    # Using npm
    
    npm install @sentry/browser

    Делаем инициализацию в главном скрипте проекта (для React и Angular):

    import * as Sentry from «@sentry/browser»;
    
    Sentry.init({ dsn: 'https://<your account key here>@sentry.io/<your project id here>' });

    Для Vue и Ember передаем еще одну обязательную строку конфигурации:

    # Vue
    
    Sentry.init({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
       integrations: [new Integrations.Vue({Vue, attachProps: true})],
    
    });
    
    # Ember
    
    Sentry.init({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
       integrations: [new Integrations.Ember()]
    
    });

    Пакет integrations устанавливается отдельно:

    # Using yarn
    
    yarn add @sentry/integrations
    
    # Using npm
    
    npm install @sentry/integrations

    Для предотвращения конфликтов и дублирования информации при подключении нескольких скриптов в одном проекте Sentry позволяет создавать отдельного клиента для каждой инициализации логирования:

    import { BrowserClient } from «@sentry/browser»;
    
    const client = new BrowserClient({
    
       dsn: '<your account key here>@sentry.io/<your project id here>',
    
    });
    
    client.captureException(new Error('example'));

    На сайте проекта есть подробная документация с примерами использования: https://docs.sentry.io.

    Статья подготовлена при поддержке облачной платформы Mail.ru Cloud Solutions.

    Что еще почитать по теме:

    1. Переиспользуемые компоненты React: как перестать писать одно и то же.
    2. Как избежать ошибок при разработке на React.
    3. Наш телеграм-канал с новостями о цифровой трансформации.

    Недавно мы рассказали о том, как начать писать программы на JavaScript:

    • что такое HTML и JavaScript;
    • из чего состоят скрипты;
    • как и где их выполнять и куда вставлять;
    • где искать готовые решения и что с ними потом делать;
    • как работать с разными элементами и обрабатывать нажатия клавиш.

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

    Что такое отладка

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

    Варварская отладка

    Самый примитивный вариант отладки — добавить в код на JavaScript метод console.log(), поместив в скобки нужные данные для отладки. Console.log() — это просто способ вывести в консоль какой-нибудь текст. 

    Например, внутри функции можно сказать: console.log(‘Вызвана такая-то функция’) — и в нужный момент мы увидим, что функция вызвалась (или нет). 

    Минус этого подхода в том, что в коде появляется много отладочного мусора. А ещё, если мы не предусмотрели логирование для какой-то функции, то мы не поймаем в ней ошибку. 

    К счастью, помимо console.log() человечество изобрело много удобных инструментов отладки. 

    Что нужно для отладки

    Для несложных проектов на JavaScript проще всего использовать встроенный отладчик в браузере Google Chrome. Единственное ограничение — он работает только с файлами скриптов, а не со встроенным в страницу кодом. Это значит, что если код скрипта находится внутри HTML-файла внутри тега <script>, то отладка не сработает.

    Чтобы открыть панель отладки в Chrome, нажимаем ⌘+⌥+I и переходим на вкладку Sources (Источники):

    Слева находится панель файлов, доступных с текущей страницы, в середине появится код нашего скрипта, а слева — панель текущего состояния кода. Пока звучит сложно, но с практикой всё станет яснее

    Открываем скрипт

    Допустим, мы хотим посмотреть, как работает скрипт из задачи про выпечку и как он перебирает все варианты. 

    Всё, что у нас есть, — это код. Чтобы мы смогли его отладить, его нужно положить в отдельный файл скрипта, присоединить к HTML-документу и запустить в браузере. 

    Открываем любой текстовый редактор, например Sublime Text, вставляем код скрипта и сохраняем файл как temp.js. Имя может быть любым, а после точки всегда должно стоять js — так браузер поймёт, что перед нами скрипт.

    После этого в новом файле вставляем шаблон пустой HTML-страницы и подключаем наш скрипт — добавляем в раздел <body> такую строку:

    <script type="text/javascript" src="temp.js"></script>

    Получиться должно что-то вроде такого:

    <!DOCTYPE html>
    <html lang="ru">
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">
    	<title></title>
    </head>
    <body>
    	<script type="text/javascript" src="temp.js"></script>
    </body>
    </html>

    Сохраняем этот код как HTML-файл, например index.html, и кладём в ту же папку, что и скрипт. Теперь заходим в папку и дважды щёлкаем по HTML-файлу, чтобы открыть эту страницу в браузере:

    Как поймать баг в коде: отладка в браузере

    На странице ничего нет, но нам нужна не страница, а скрипт, поэтому находим слева наш файл temp.js и нажимаем на него — откроется код скрипта. Теперь можно начинать отладку:

    Как поймать баг в коде: отладка в браузере

    Добавляем точки остановки

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

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

    Брейкпоинт нужен для того, чтобы выполнить скрипт по шагам, начиная с первой команды. Чтобы его установить, нажимаем на номер строки с первой командой — в нашем случае это строка 2:

    Как поймать баг в коде: отладка в браузере

    Обновим страницу и увидим, что скрипт начал работу и остановился. Но он остановился не на второй строке, а на шестой — всё потому, что это первая строка в скрипте, где происходит какое-то действие. Дело в том, что просто объявление новых переменных не влияет на работу скрипта, поэтому он ищет первую команду с действием. В нашем случае — это цикл for:

    Как поймать баг в коде: отладка в браузере

    Пошаговая отладка

    Чтобы посмотреть на работу скрипта по шагам, надо нажимать F9 или стрелку вправо с точкой на панели отладки:

    Как поймать баг в коде: отладка в браузере

    Каждый раз, как мы будем нажимать F9 или эту кнопку, скрипт будет переходить к следующей команде, выполнять её и снова становиться на паузу:

    Как поймать баг в коде: отладка в браузере

    Добавляем переменные для отслеживания

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

    Чтобы добавить переменную и видеть её значение во время выполнения, в панели отладки в разделе Watch нажимаем плюсик, вводим имя переменной, выбираем её из списка и нажимаем энтер:

    Как поймать баг в коде: отладка в браузере

    Теперь видно, что на этом шаге значение переменной a равно нулю:

    Как поймать баг в коде: отладка в браузере

    Точно так же добавим остальные переменные: i, b, c. Так мы увидим, что первые два цикла только начались, а внутренний прошёл уже три итерации:

    Как поймать баг в коде: отладка в браузере

    Так, нажимая постоянно F9, мы прогоним весь скрипт до конца и посмотрим, при каких значениях какие условия выполняются и как находится решение:

    Как поймать баг в коде: отладка в браузере

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

    Отладка брейкпойнтами

    Допустим, нам важно понять, в какой момент скрипт находит и выдаёт решение. Глядя в код, мы понимаем, что как только скрипт дошёл до команды console.log() — он нашёл очередное решение. Это значит, что мы можем поставить брейкпоинт только на эту строчку и не прогонять вручную весь скрипт: он сам остановится, когда дойдёт до неё, а мы сможем посмотреть значения переменных в этот момент.

    Для этого:

    1. Нажимаем снова на строку 2 и убираем предыдущую точку остановки.
    2. Ставим брейкпоинт на строку 20 — там, где происходит вывод решения в консоль. 
    3. Нажимаем F8. 

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

    Как поймать баг в коде: отладка в браузере

    Таких точек остановки можно поставить сколько угодно и в любой момент — на каждой из них отладчик остановится и покажет текущее состояние скрипта.

    Зачем это всё

    Отладка нужна, чтобы найти ошибки в программе. Если мы видим, что на очередном шаге в переменной находится не то, что мы ожидали увидеть, значит, что-то в коде идёт не так. Мы ставим брейкпоинт на начало нужных команд, запускаем отладку и находим команду, которая приводит к ошибке.

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

    Вёрстка:

    Кирилл Климентьев

    Понравилась статья? Поделить с друзьями:
  • Как найти ошибку в коде приложения
  • Как найти ошибку в коде питон
  • Как найти ошибку в коде паскаль
  • Как найти ошибку в коде на сайте
  • Как найти ошибку в коде игры