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

Стандартный вид Ошибки 404 в Nginx
Стандартный вид Ошибки 404 в Nginx

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

Пример страницы для Ошибки 404
Пример страницы для Ошибки 404

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

Для упрощения интеграции, утилита автоматически создает сниппет с конфигурацией веб сервера, который легко может быть добавлен в конфигурацию вашего веб сервера. На текущий момент сниппет создается только для Nginx. Другие виды серверов будут добавлены позже (в качестве альтернативы, вы можете создать Pull Request с таким улучшениями, либо оформить Feature Request).

Использование

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

$ git clone git@github.com:sapachev/error-pages.git
…
$ npm install --production
…
$ npm run build
…
INFO: Start building process
INFO: Flush build directory '/home/error-pages/dist'
INFO: Compile pages from source data:
 • /home/error-pages/dist/400.html
 • /home/error-pages/dist/401.html
 • /home/error-pages/dist/403.html
 • /home/error-pages/dist/404.html
 • /home/error-pages/dist/410.html
 • /home/error-pages/dist/500.html
 • /home/error-pages/dist/502.html
 • /home/error-pages/dist/503.html
 • /home/error-pages/dist/504.html
INFO: Compile web servers config snippets from source data:
 • /home/error-pages/dist/nginx-error-pages.conf
INFO: Build Tailwind CSS styles
INFO: Run 'INPUT="/home/error-pages/themes/minimalistic/@assets/css/main.twnd.css" OUTPUT="/home/error-pages/dist/@assets/css/main.css" npm run build:tailwind' command
INFO: Tailwind CSS styles were built
INFO: Copying assets to '/home/error-pages/dist/@assets' directory
INFO: Building process was completed in 1.727s

Продвинутое использование

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

Основная конфигурация утилиты хранится в файле config.json в корневой папке, которую можно менять в соответствии со своими требованиями:

{
  "tailwind": true,
  "theme": "minimalistic",
  "locale": "en"
}

Шаблоны

Все шаблоны хранятся в папке themes, где стандартной темой является minimalistic, которую можно изменить или добавить новую. Каких‑то особых требований к шаблонам страниц нет: каждый шаблон является обыкновенным HTML документом, с внедренными переменными, на месте которых будут текстовки из файлов локализации. Для обработки внедренных переменных используется библиотека mustache.js. Таким образом, если нужно реализовать какую‑то особенную логику в своих шаблонах, то вы можете ознакомиться с документацией этой библиотеки для определения имеющихся возможностей шаблонизации.

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

Стили

Стилизация шаблонов базируется на фреймворке Tailwind CSS. С помощью этого фреймворка, можно быстро описывать стили страниц без необходимости писать отдельный CSS код. Точкой входа для стилей Tailwind должен быть файл themes/<name>/@assets/css/main.twnd.css. Из него в дальнейшем будет создан файл main.css, который содержит скомпилированные и минифицированные стили. В дополнение, можно настроить Tailwind с помощью создания кастомной конфигурации, расположенной в файле theme.tailwind.config.js в корне папки с темой, и описать в ней любые опции Tailwind. Полный список опций Tailwind доступен в документации самого Tailwind.

Однако, если по каким-то причинам использование Tailwind не требуется (например, стили уже описаны ранее в CSS), компиляцию стилей Tailwind можно отключить в основной конфигурации утилиты (файл config.json). В этом случае шаг сборки стилей будет просто пропущен без какого-либо влияния на финальный результат.

Текстовые сообщения и Локализация

Все текстовые сообщения хранятся в JSON файлах, разделенных по признаку языка, и расположены в папке src. Каждая страница создается из соответствующего ей файла локализации вида <Код HTTP>.json (<Код HTTP> – это число, соответствующее коду ошибки HTTP). Таким образом, если нужно создать страницу для кода, который еще не описан, то просто создайте соответствующий JSON файл, содержащий описание этого статуса в соответствующих свойствах.

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

Для локализации страниц, просто создайте новую папку в директории src, содержащую JSON файлы с текстами страниц. Создавая JSON файлы, вы можете описать любой набор HTTP кодов (например, только для 400-ых ошибок) – просто следуйте конвенции именования, и не забывайте выделять общие тексты в файл common.json.

Конфигурации сервера

В процессе работы, Утилита автоматически создаст сниппет для вашего сервера, который будет содержать лишь те страницы, которые были созданы. Данный сниппет будет содержать настройки обрабатываемых ошибок, и указывать на страницы, которые будут их представлять. Как было сказано ранее, на данный момент только Nginx поддерживается.

Для использования полученных страниц, остается только скопировать на сервер все файлы из папки dist и включить использование сниппета в уже существующей конфигурации сервера. В соответствии с шаблоном сниппета, все страницы должны быть расположены в папке /usr/share/nginx/html/error-pages. В случае если настройки в снипетта не подходят, то вы можете отредактировать шаблон сниппета в папке snippets. Так же как и для тем оформления, шаблоны конфигураций поддерживают mustache.js, тем позволяя реализовать в шаблоне любую логику (списки, условия и т. д.).

Сам по себе конфиг, я рекомендую располагать в папке /etc/nginx/snippets/, а для его подключения использовать строчку конфигурации: include /etc/nginx/snippets/nginx-error-pages.conf;. Разумеется, это не более чем рекомендация, т.к. в реальности всё может быть иначе или сложнее.

Ниже приведен простой пример конфигурации веб‑сервера с включенным в нее сниппетом кастомных ошибок:

server {
    server_name example.com;
    access_log /var/log/nginx/example.access.log;

    include /etc/nginx/snippets/nginx-error-pages.conf;

    location / {
        root /data/www;
    }
}

Демо

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

Сообщение об ошибках и запрос новых функций

Код утилиты нельзя назвать каким‑то сложным, однако, несмотря на этот факт, все значимые части покрыты юнит‑тестами. Впрочем, это не является гарантией отсутствия каких‑либо ошибок, поэтому если вы столкнетесь с какими‑то проблемами, то, пожалуйста, сообщите мне о них, через создание Issue в репозитории проекта: https://github.com/sapachev/error‑pages/issues

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

Участие в разработке

Проект открыт для всех желающих, и если у вас есть идеи, а главное желание и возможности их реализовать, то с радостью рассмотрю их в виде Pull Request. Со своей стороны готов предоставить вам поддержку в реализации вашей задумки. Не стесняйтесь спрашивать меня о коде, и возможных решениях вашей идеи.

Комментарии (17)


  1. mfisgood
    00.00.0000 00:00

    Спасибо за материал! Легкий и занятный гайд


  1. sa10ry
    00.00.0000 00:00

    Ваш сайт наверное упал :)


    1. Unixspv Автор
      00.00.0000 00:00

      Там чистая статика, так что надо сильно постараться что бы его положить :)


      1. sa10ry
        00.00.0000 00:00

        На дэсктопе - дэмо работает.

        Через мобильное приложение Харбр (iOS) - не переходит/не открывает ссылку


        1. Unixspv Автор
          00.00.0000 00:00

          Странно, но, к сожалению, не могу проверить, т.к. нет iOS-девайсов :(


  1. fk0
    00.00.0000 00:00
    -2

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


    1. gmtd
      00.00.0000 00:00

      Наверное, если клепаешь сайты по нескольку штук в день


      1. losacef
        00.00.0000 00:00

        и хочешь, чтобы за это платили деньгами, а не едой.


    1. Unixspv Автор
      00.00.0000 00:00

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


      1. fk0
        00.00.0000 00:00

        Поясню свою мысль. Что такое сайт -- это, в конечном счёте, описание того, что я хочу получить на каком-то языке. И у меня есть варианты:

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

        2. использовать общепринятый и известный мне язык, который в силу разных нужд так или иначе знать будешь (html).

        И самое главное, если в пункте 1 нужно что-то не предусмотренное автором -- финиш. Всё равно идёшь в пункт 2.

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

        И даже если стоит задача генерации статических страниц из шаблона, для этого опять же не нужна специальная программа. Достаточно любого общеупотребительного макропроцессора. Хоть C-препроцессор, хоть m4, хоть микрософтовский T4, хоть макропроцессор рализованный средствами скриптового ЯВУ (подстановка переменных и функций в HERE-документы в bash, python, в Tcl шикарный макропроцессор). Хотя последнее уже не очень, так как опять же требует обучения (нет чётких правил, нет документации).

        Хотя на мой взгляд для HTML лучшим вариантом генерации является вообще XSLT. Т.е. шаблоны делаются на XML (XHTML), входные данные подготавливаются как xml или текстовые файлы и трансформируются каким-нибудь xsltproc в простейшем случае, или saxon в сложном (XSLT 2.0), в результирующий HTML. XSLT вообще это технология которую часто незаслуженно забывают.

        PS: Авторский node.js, а проще говоря Javascript тоже на самом-то деле не самая плохая идея. Работа с html-шаблонами через DOM-представление вполне себе широко известный и стандартный подход. Это значительно лучше, например, чем скрипт на питоне который будет через printf формировать результат. Однако сам node.js -- несколько сомнительная технология. Т.к. часто не работает без подключения к интернету (нужно скачать 100500 внешних зависимостей из сомнительных источников).

        PPS: Но вообще если вспоминать JS, то непонятно зачем там генерировать статические страницы. Достаточно одной на все случаи жизни. В которой будет и шаблон и скрипт же, который на ходу из шаблона сделает что нужно. Да, в браузере может не быть Javascript (но что сейчас в таком браузере можно увидеть???) Да в конце концов шаблон можно сделать на CSS и без JS. И параметризовать его через SSI (Server Side Includes) в одном единственном месте. А если у кого-то lynx, то проще вообще ничего не делать и пользоваться стандартными кодами без красивых шаблонов.


        1. Unixspv Автор
          00.00.0000 00:00

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

          Что касается XSLT, то от себя лично могу сказать что опыт взаимодействия с этой технологией был скорее отрицательным: одна лишь отладка шаблонов чего стоила. Ну и это как ни крути, но дополнительная прослойка над HTML. А вообще современная веб-разработка - это вполне устоявшийся стек, где JS, HTML и CSS во главе. Да, мир JS-разработки, в каком-то смысле, усложнен NPM (и прочими пакетными менеджерами), но это текущая реальность с которой сталкивается любой веб-разработчик.

          Касательно SSI соглашусь отчасти. Сам, порою, с теплотой вспоминаю эту технологию, однако, сравнивая статичный HTML и HTML+SSI(+JS), то выбор кажется очевидным. Ну и опять же: данный инструмент - это лишь возможность, а не обязательство. Тот, кому это не требуется, найдет другое решение, или будет довольствоваться тем, что даётся веб-серверами из коробки.

          В любом случае спасибо за развернутый комментарий и ностальгические воспоминания о технологиях прошлого :)


          1. fk0
            00.00.0000 00:00

            Сейчас я побегу скачивать готовую сборку на боевой сервер! А завтра там раз -- и Cлaвa Укpaiнe поперёк экрана. И не потому, что автор верный последователь идей Бaндepы, а потому, что у него неосмотрительно npm подтянул какое-то непотребство через зависимость зависимостей одной из зависимостей.

            XSLT это не прслойка, а ДЕКЛАРАТИВНЫЙ язык программирования. Много лучший для своих задач, чем типичные императивные ЯВУ. Потому, что на императивном ЯВУ сколько-нибудь сложный аналог этих шаблонов превращается в изобилующее багами макаронное месиво. Это примерно как сравнивать языки со строгой типизацией и скриптовые языки где всё есть строка. На последних можно быстро начать, но так же быстро погрязнуть.

            Не называл бы SSI и вообще серверную генерацию страниц технологией прошлого. Скорей, увы, наоборот. Это и есть настоящий WEB. А загрузка в браузер фактически программ для виртуальной машины, как сейчас принято -- это не WEB. Это чёрти что, которое невозможно сохранить, невозможно индексировать и т.д. и т.п. Это не WEB, это не то, что изобретал Тим Бернерс Ли. Это скорей прошлое. Это та же система MINITEL но на современной базе. WEB -- это общедоступная, публичная база знаний. Всемирная библиотека. А современный интернет превратился в набор серверов принадлежащий поставщикам услуг, и набор аппликаций загружаемых с этих серверов в браузер пользователю. Две большие разницы. Начиная с того, что разные пользователи видят разное содержимое, часто дать ссылку невозможно, везде нужна авторизация и всё направлено не на публикацию знаний, а на доставку развлекательного контента и "монетизацию". :-(


            1. Unixspv Автор
              00.00.0000 00:00

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


  1. CoolCmd
    00.00.0000 00:00

    ну и зачем пользователю число 404 на пол экрана?


    1. Unixspv Автор
      00.00.0000 00:00

      Это пример страницы. При желании можно сделать какой угодно дизайн страницы. В статье всё подробно описано как сделать это.


  1. RouR
    00.00.0000 00:00
    +1

    Демо

    Вот только в итоге 404 страница отдается со статусом 200. Не делайте так, это заметание проблемы "под ковёр". В мониторинге должен быть виден правильный статус.


    1. Unixspv Автор
      00.00.0000 00:00

      Спасибо за ценную находку! Поправил этот баг в шаблоне сниппета nginx -- теперь приходит корректный статус, в т.ч. в демо.