Содержание сообщения об ошибке

Перевод краткого руководства от UX-писателя BBC Эми Лик.

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

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

Прежде чем составлять сообщение, убедитесь, что знаете ответы на эти вопросы:

  • Что произошло?
  • Как это случилось?
  • Как это исправить?
  • Ошибся пользователь, система или все вместе?
  • Можно ли изменить текст этого сообщения? Операционная система может контролировать некоторые сообщения об ошибках.

Структура текста

Чтобы исправить ошибку, сначала нужно узнать, в чём она состоит. Сообщение будет выглядеть примерно так: ошибка → как её исправить.

Довольно простая структура. Вот пример реального сообщения об ошибке в одну строчку.

«Файл повреждён. Попробуйте выбрать другой»

Бывает, система не может указать, что именно произошло.

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

«Проблема с подключением. Проверьте ваше интернет-соединение и попробуйте снова». Кнопки: «Попробовать снова» и «Отмена»

Пишите коротко и ясно

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

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

Как надо писать: «“Pictures” уже существует. Выберите другое имя». Как не надо писать: «Не можем переименовать “Pictures”, поскольку файл или папка с таким именем уже существует. Укажите другое имя»

Системная ошибка

Если ошибка произошла по вине системы, извинитесь перед пользователем. Но если в этом виноват пользователь — будьте аккуратны. Извинения звучат неискренне там, где им не место. К тому же неуместные извинения могут сбить с толку — пользователь подумает, что не виноват в ошибке, раз система говорит «простите».

Чтобы принять ответственность за случившееся, используйте активный залог. Пишите: «Мы не можем сохранить ваши изменения», а не «Ваши изменения не могут быть сохранены».

Ошибка пользователя

Иногда ошибки появляются по вине пользователя. Но сообщить об этом можно мягко и без осуждения.

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

Пишите «Пожалуйста, введите своё имя» вместо обвиняющего «Вы забыли вписать своё имя»

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

Используйте правильный тон

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

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

Несерьёзное сообщение: «Этот пароль неверный. Попробуйте ещё раз». Серьёзное сообщение: «Эта карта была отклонена. Попробуйте другой способ оплаты»

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

Что случится, если нажать на кнопку

Для устранения некоторых ошибок могут потребоваться СТА-кнопка или ссылка. Иногда бывает нужна кнопка отмены.

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

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

Сверху: система пока не может открыть PicEditor, и нужно перезагрузить компьютер, чтобы закончить установку. Кнопка «Окей, перезагрузить» (СТА).  Снизу: недостаточно места, чтобы скачать файл.  Кнопка: «Окей, понятно» (отклонить)

Время и место

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

  1. Что вызывало это сообщение?
  2. Когда оно появилось?
  3. Где появилось?
  4. Понятно ли, с чем оно связано?

Задавая эти вопросы, не забывайте, что есть пользователи с ограниченными возможностями. Это подталкивает к новым вопросам:

  • Как мы можем помочь всем пользователям перейти к решению?
  • Может ли ошибка слишком встревожить пользователя или быть навязчивой, появившись в этот конкретный момент?
  • Как связать сообщение с соответствующим разделом визуально и не визуально?

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

Ключевые рекомендации

  • Определите, с какой ошибкой столкнулся пользователь и как её исправить.
  • Пишите коротко и ясно.
  • Используйте нужный тон и только уместные извинения.
  • Дайте понять, что будет, если нажать на кнопку или ссылку.
  • Учитывайте время и место появления сообщения. Не забывайте про то, как воспримут его пользователи с ограниченными возможностями.

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

В основе статьи доклад Антонины Хисаметдиновой с Heisenbug 2017 Moscow, которая занимается проектировкой пользовательских интерфейсов в компании Собака Павлова.

Кроме того, на Медиуме есть цикл статей «Руководство по проектированию ошибок». Цикл еще не дописан до конца, но дает более полную и цельную картину по теме статьи.

Ошибочный сценарий

Раз за разом мы проектируем основные сценарии самых разнообразных сервисов. В случае интернет-магазина основной будет таким:

Человек заходит на сайт, выбирает товар, заказывает его доставку; оплачивает и получает заказ.

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

Всё это — ошибочные сценарии, возникающие, когда что-то идет не так.

Продуктовые команды часто не уделяют достаточно внимания таким сценариям. Например, очень типичная история: «Что-то пошло не так. У нас проблемы, поэтому просто закройте это сообщение».

Еще пример: «У нас ошибка. Повторите вашу попытку позже»:

И еще одна категория ошибок — моя любимая: неизвестные ошибки.

Зачем работать над ошибочными сценариями?

Обосновать бизнесу необходимость проработки ошибочных сценариев бывает очень сложно. Зачем нам возвращаться назад и что-то исправлять, когда впереди у нас новые фичи? Но у меня есть четыре железных аргумента, которые помогут продемонстрировать вашему product owner’у или бизнесу необходимость такой работы.

Хорошее сообщение об ошибке снижает нагрузку на техническую поддержку и персонал

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

Обратите внимание, 400 человек в месяц звонят просто из-за того, что не могут войти или корректно ввести логин / пароль в соответствующей форме на сайте.

Хорошее сообщение об ошибке помогает пользователю не потеряться в воронке конверсии

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

Хорошее сообщение об ошибке обучает работе с сервисом

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

Хорошее сообщение об ошибке позволяет сохранить доверие к сервису в трудную минуту

Это последний, но немаловажный аргумент.

Вообще тема доверия «человек-технология» исследуется довольно давно. Сейчас мы уже достаточно доверяем технологиям. Например, мы никогда не будем перепроверять, отправил ли мессенджер сообщение адресату, или как калькулятор сложил или умножил трехзначные числа (к сожалению, правда, не все сервисы могут похвастаться таким уровнем доверия, как калькуляторы).

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

Из-за чего возникают ошибки

Я несколько раз упомянула «хорошее сообщение об ошибке». Настала пора поговорить о том, что это значит. И для начала разберемся, из-за чего в принципе возникают ошибки.

  • первое, что приходит в голову, это какие-то глобальные сбои или технические работы на сервисе;
  • специфические баги;
  • ошибки пользователя.

Но это далеко не всё. Еще есть:

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

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

Глобальные сбои

Давайте начнем с ситуации, когда ваш сервис полностью недоступен.

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

Хороший вопрос: что в такой ситуации делать?

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

Давайте посмотрим на сообщения, которые в этот момент выводятся:

Они достаточно простые и некоторые из них даже честно извиняются. Но пользователи все равно чувствуют себя некомфортно и пытаются понять, в чем же дело; повторяют вход далеко не через 15 минут; тыкают, куда попало.

Как им помочь?

Подумайте о последствиях

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

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

Но «скоро» — это когда?

Пользователю не нужно знать, когда вы всё поправите, с точностью до минуты. Но им нужно понимать какие-то значимые временные ориентиры, например, 15 минут, один час, пять часов или даже сутки. Это поможет им сориентироваться в пространстве и спланировать управление своими деньгами.

Еще один резонный вопрос (в ракурсе финансового сервиса): работают ли карточки?

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

Еще одна история — тут зарплата или перевод должны быть; а когда придут эти деньги?

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

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

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

Предупредите заранее

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

Отдельно стоит сказать про профессиональные сервисы, от которых ежедневно зависит работа пользователей. Например, сервис Антиплагиат иногда выводит такое сообщение о проведении технических работ:

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

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

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

Специфические баги

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

Для нас баги — это знакомая история. Мы четко классифицируем их по разным параметрам: степени опасности, необходимости исправления и т.п.

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

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

  • раздел «Контакты» и обратная связь;
  • онлайн-консультант и звонок в техподдержку;
  • социальные сети и чаты компании;
  • отзывы (App Store и Play Market)!!!
  • блоги и форумы.

Мы предполагаем, что пользователь когда-нибудь проскролит страницу вниз до подвала, найдет там вкладку «Контакты». В разделе контактов найдет среди карт, отделов, офисов продаж и прочего маленькую кнопочку «Обратная связь», нажмет на нее, выберет тему обращения. Напишет подробное письмо о том, как воспроизвести эту ошибку, приложит скриншоты и отправит.
Да, действительно, такие письма приходят. Но если ошибка очень плохая, человек может сразу оставить отзыв с низкой оценкой на App Store, где также подробно распишет, чем ему ваш сервис не нравится.

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

Или могут вообще перестать пользоваться вашим сервисом, как неработающим.
Поэтому в багтрекере ВКонтакте висит такой вот тикет, который называется «отсутствие кнопки «Сообщить о баге»»:

Действительно, это проблема очень многих сервисов.

Создайте специальные окна для сбора обратной связи

Но есть и позитивные примеры, например, Semrush. Почти по всему сервису размещены специальные окна, которые нацелены на то, чтобы забирать фидбэк от человека.

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

Если нельзя исправить баг быстро, предупредите о нем

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

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

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

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

Ошибки пользователей

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

Первый пример узкого места многих сервисов — это, конечно, вход / регистрация:

Например, поле входа в InVision. Маленькая красная полосочка — это, в принципе, всё сообщение об ошибке. Наверное, когда дизайнер его рисовал, думал, что пользователь без труда прочитает сообщение: «Упс, комбинация email и пароля не верна». Проверит сначала email, затем пароль, и снова нажмет кнопочку войти. Но статистика подсказывает, что пользователь делает несколько попыток входа и ввода пароля, прежде чем догадывается, что проблема в email-адресе.

Это происходит, потому что внимание пользователя в момент входа сосредоточено в одной очень узкой области — она называется фокусом внимания:

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

Фишка 1. Разместите сообщение в фокусе внимания

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

Фишка 2. Показывайте, где именно ошибка

Подсвечивание обоих полей — это и есть вторая фишка.
Но и это не всегда помогает.

Например, дизайнеры компании Adobe считают, что пользователи действительно это всё читают:

Еще один классический пример предлагает Xiaomi:

Или, например, сайт Госуслуги (как и многие другие) просто дублирует название поля заголовка в ошибку:

Фишка 3. Используйте понятные и короткие формулировки

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

Но в окружении интерфейса и текущих задач у пользователей это выглядит вот так:

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

Ему неохота читать ваши тексты, он хочет дальше решать свои задачи.
Поэтому, сокращая формулировку и размещая сообщение в зоне фокусировки, мы можем быстрее донести смысл.

Фишка 4. Подскажите, как исправить ошибку

Кто сталкивался с кассами самообслуживания?

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

В чем была проблема? Пользователи забывают положить маленькие товары на другую сторону. Поэтому разработчики добавили звуковой сигнал, после чего в 90% таких ситуаций покупатели стали обходиться без помощника. Сигнал заставлял человека поднимать глаза на экран кассы и выходить из состояния, когда он сканирует свою огромную корзину покупок: «Точно, я не положил воду».

У этого сообщения об ошибке есть две из перечисленных «фишек»: оно подсказывает, где именно ошибка, и обучает работе с сервисом.

Фишка 5. Сохраняйте работу пользователя

Последнее, но самое интересное.

Давайте сразу на примере. Это кусочек пути регистрации (в очередной раз напоминаю, что регистрация — достаточно слабое место у очень многих сервисов):

Чтобы вообще начать пользоваться финансовым сервисом Revolut, я должна сначала подтвердить свой номер телефона. Обратите внимание, они уже автоматически определили и подставили код страны. Спасибо ребятам.

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

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

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

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

Проблемы подключенного сервиса

Тестируйте API подключенных сервисов

На днях мне попался интересный отчет на сайте APIFortress. Там был рассказ про компанию, которая поставляла стоковые изображение своим партнерам. Одним из них было агентство, которое занималось сувениркой с мопсами.

Однажды этот мопс-партнер позвонил в стоковую компанию и пожаловался на поломку сервиса.

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

Учите их различать проблемы

Иногда недостаточно просто знать, что где-то там у вас проблема, потому что пользователи будут видеть странные окна, которые не будут им помогать:

И в интерфейсе эту проблему не решить.

Поэтому очень важно потратить усилия, чтобы научить ваш сервис различать причины проблем с API.

Предусмотрите в интерфейсе оповещение о проблемах

Очень хороший пример — сервис-автоматизатор ifthisthenthat. С помощью связок API различных сервисов (например, умного дома или социальных сетей) они заставляют сторонние сервисы делать определенные вещи. Например, если я опубликовала пост в Instagram, он автоматически уходит в мой Facebook. Или, если я вышла из дома, сервис определяет по моей геопозиции, что я нахожусь в офисе, и проверяет, выключила ли я все свои смарт-утюги. А если не выключила, то выключает.

Эти ребята проделали очень большую работу, и не только в интерфейсе.

Во-первых, они выделяют отдельную вкладку для ошибок. Все неудавшиеся операции собираются в этот лог.

Они определяют разные типы ошибок:

В первом случае — сервис Instagram офлайн, и мы понимаем, в чем проблема. Возможно, мы временно вышли из зоны действия сети.

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

Внешние проблемы

Что такое внешние проблемы в моем пользовательском понимании?

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

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

Хороший пример — отсутствие интернет-соединения в коммуникаторе Slack. Если во время работы у меня отвалился интернет, я вижу вот такое сообщение сверху:

Как мы помним про сообщения об ошибках пользователей, в момент ввода какого-то текста пользователь сконцентрирован в этой области:

Slack об этом не забывает и подсвечивает поле желтеньким.

При этом он не блокирует мне набор сообщения. Я могу продолжить писать его дальше, но при попытке отправить Slack-бот отправляет мне вот такое сообщение:

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

Большая проблема с внешними ошибками, которая пришла к нам еще из «древних» времен, когда продукты создавались инженерами для инженеров, — это содержание текстов об ошибках:

Они написаны таким языком, как будто мы сейчас до сих пор подразумеваем, что пользователь знает, что такое firewall, ftp, dll, ядро, kernel и так далее.

Четко разделите уровни компетенции

Техническому специалисту мы показываем одну информацию, а пользователю — другую.

Наверное, стоит отдельно сказать про то, как люди в принципе общаются с техподдержкой.

Для многих это действительно большой стресс. Большая часть сообщений об ошибках совершенно не подразумевает, что они должны быть поняты. Человек, который даже не знает английского языка, пытается как-то объяснить: у меня там что-то сломалось. Он испытывает очень сильный дискомфорт. И всё это влияет в целом на его опыт общения с вашим сервисом. Поэтому старайтесь создавать такие сообщения, которые пользователь сможет осознать и своими словами передать техподдержке.

Например, это фото 3D-принтера, который четко и ясно (с помощью маленького экранчика) говорит, что температурный сенсор испортился — произошла ошибка, поэтому он остановился. Свяжитесь с техподдержкой. Пользователь легко может понять, в чем дело, и для него не сложно описать эту проблему своими словами без технических терминов:

Помогите пользователю оценить приоритет проблемы

Что это значит?

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

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

А есть еще такая категория: «У меня там до зарплаты неделька… ничего же не случится?»
Поэтому очень важно дать возможность пользователю оценить опасность этой проблемы. Пользователь в этот момент не хочет лезть в какие-то сложные инструкции. Если действительно произошло что-то страшное, важно указать одно —  серьезность проблемы. Иногда «эксплуатацию продолжать нельзя», а иногда и правда можно подождать до зарплаты.

Крайне необычное поведение пользователей или сервисов.

Бывает ситуация, как на графике. Что вызвало такой резкий скачок? К примеру, это температура в двигателе повысилась? Или это просто датчик какой-то забарахлил?

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

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

Но за PewDiePie тоже стояла большая армия поддержки. И на игры Шона Ванамана в Steam (сервис, который продает эти игры) посыпались сотни негативных отзывов. Эти отзывы не отражали качество игры, но могли негативно сказаться на ее продажах. И Steam проделал просто потрясающую работу: они обратили внимание пользователя, что произошло, что замечен нетипичный объем отрицательных отзывов с 11 сентября:

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

Дополнительные возможности — скрытый потенциал

Не все ошибки — просто баги. У многих есть скрытый потенциал. Давайте про это немного поговорим.

Обучайте через ошибки

Во-первых, как я уже говорила ранее, через ошибки можно и нужно обучать.
Например, сервис Skyeng — это онлайн школа английского языка, которая работает только через браузер Google Chrome. Этот браузер автоматически (по дефолту) иногда блокирует входящие видеозвонки или аудиозаписи. И в такой ситуации Skyeng вешает кнопочку, которая ведет на вполне подробную инструкцию:

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

Еще один пример — SEMrush. Это окно входа в сервис:

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

Выводите из тупика

Еще один потенциал сообщений об ошибках — это вывод из тупика.

Часто ошибки являются абсолютно тупиковыми сценариями. Пользователю нужно вспоминать контекст и возвращаться по сценарию выше.

Например, возьмем сервис Avito. Там есть вкладка «Сохраненные поиски»:

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

А можно было сделать вот так:

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

Доступность

Есть еще одна важная тема, которую я хотела обсудить, это доступность интерфейсов.

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

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

Например, многие используют только цветовую индикацию ошибки. Так делать не стоит, потому что есть дальтоники:

Многие дизайнеры скажут: «Я всё проверил в специальном сервисе, который показывает, как видит дальтоник». Но на самом деле эти сервисы никогда не покажут точной картины, потому что все дальтоники видят по-разному. И даже если вы подберете яркость / контрастность, всё равно существует риск, что пользователь-дальтоник эту ошибку не распознает.

Например, поле регистрации во Wrike содержит как раз такую ошибку:

У них реализована чисто цветовая дифференциация — при ошибке красным подсвечивается обводка и текст внутри поля. Лучше всего добавить какое-то текстовое сообщение или символ.

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

Человек просто сломает глаза при попытке прочитать такой текст.

Проводите Accessibility testing для сценариев с ошибками

Бизнес-ценность

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

Что нужно делать? Мой коллега выстроил работу в своем коллективе следующим образом. Все ошибки, которые возникают, сначала собираются в какой-то один большой мешок (log). Оттуда вычленяются только те ошибки, которые повторяются.

Повторяющиеся ошибки уже имеют бизнес-ценность. Это те ошибки, на которые стоит потратить время.

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

Я понимаю, что интерфейс — это не всегда часть вашей работы. И даже далеко не все product owner’ы горят желанием выстраивать работу с ошибками в своей команде, потому что это не всегда выгодно (выгода, если и есть, иногда не видна сразу). Но моя цель — немного расширить ваш образ мышления и задать вопрос: вы делаете только свою работу или вы делаете классный продукт?

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

Резюме

Что я предлагаю вам делать со всей этой информацией?

  1. Когда вы придете на работу, обсудите доклад с командой и владельцем продукта. Особенно полезно зайти к UX’ерам или к дизайнерам.
  2. Проверьте, насколько ваши сообщения об ошибках полезны пользователям.
  3. После этого вы сможете комплексно посмотреть на свой продукт, найти его слабые места, которых раньше, возможно, не замечали, и улучшить ошибочные сценарии.
  4. И еще один очень важный пункт в контексте тестирования — ошибочные сценарии тоже нужно тестировать и часто на равных правах с остальными.

Что почитать?

Здесь есть несколько ссылок:

  1. «Release It!: Design and Deploy Production-Ready Software», Michael T. Nygard
  2. «How to write a great error message», Thomas Fuchs, https://goo.gl/4L8YWo
  3. Architecting Your Software Errors For Better Error Reporting, Nick Harley, https://goo.gl/7em6cQ

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


Если тема тестирования и обработки ошибок вам так же близка, как и нам, наверняка вас заинтересуют вот эти доклады на нашей майской конференции Heisenbug 2018 Piter:

  • Пишем UI тесты для Web, iOS и Android одновременно # python (Игорь Балагуров, Uptick)
  • Web Security Testing Starter Kit (Андрей Леонов, SEMrush)
  • Бета-тестирование ВКонтакте (Анастасия Семенюк, ВКонтакте)
ArgumentError: при назначении атрибутов вы должны передать хэш как аргумент
Assert Failed: значения в hash-map должны быть генераторами

Что не так с этими сообщениями об ошибках (и тысячами других, на них похожих)?

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

Почему эта ошибка в CoffeeScript так часто появлялась в вопросах на StackOverflow?

[Mon Jun 08 2015 10:19:02 GMT+0100 (BST)] ERROR Unable to load /Users/tcrayford/proj/yeller/hubot/scripts/earl: SyntaxError: unmatched OUTDENT
  at exports.throwSyntaxError (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/helpers.js:197:13)
  at Lexer.exports.Lexer.Lexer.error (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/lexer.js:778:14)
  at Lexer.exports.Lexer.Lexer.pair (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/lexer.js:690:16)
  at Lexer.exports.Lexer.Lexer.outdentToken (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/lexer.js:378:16)
  at Lexer.exports.Lexer.Lexer.closeIndentation (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/lexer.js:550:19)
  at Lexer.exports.Lexer.Lexer.tokenize (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/lexer.js:34:12)
  at exports.compile.compile (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/coffee-script.js:35:36)
  at Object.loadFile (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/coffee-script.js:176:14)
  at Module.load (/Users/tcrayford/proj/yeller/hubot/node_modules/hubot/node_modules/coffee-script/lib/coffee-script/coffee-script.js:211:36)

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

Контекст — наше все

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

ArgumentError: при назначении атрибутов вы должны передать хэш как аргумент,
но вы передали #<User id:12345 email:tom@example.com>

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

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

Для Clojure-истов: используйте ex-info

Следующая информация предназначена только для тех, кто пишет на Clojure. Используйте функцию ex-info при дизайне исключений и указании контекста:

(ex-info "какое-то сообщение об ошибке" {:wrong-args [1 2 3]})

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

Как это касается меня?

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

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

Перевод статьи «The art of the good error message»

Расшифровка 55 состояний прикладного протокола HTTP (протокол передачи гипертекста): от информационных сообщений до ошибок.

Во время запроса информации с удаленного веб-сервера может возникнуть ошибка. Тогда веб-сервер посылает в ответ код ошибки HTTP. Например 404 — Not Found (ресурс не найден).

Коды состояния HTTP состоят из трех цифр от 100 и до 510. Они делятся на следующие группы:

  1. Информационные (100-105).
  2. Успешные (200-226).
  3. Перенаправление (300-307).
  4. Ошибка клиента (400-499).
  5. Ошибка сервера (500-510).

Чтобы получить сведения об ошибке, введите её код в поле поиска по странице. Для этого нажмите сочетание клавиш CTRL + F и укажите номер.

100

Continue
Cервер удовлетворён начальными сведениями о запросе, клиент может продолжать пересылать заголовки. Появился в HTTP/1.1.

101

Switching Protocols
Сервер предлагает перейти на более подходящий для указанного ресурса протокол; список предлагаемых протоколов сервер обязательно указывает в поле заголовкаUpdate. Если клиента это заинтересует, то он посылает новый запрос с указанием другого протокола. Появился в HTTP/1.1.

102

Processing
Запрос принят, но на его обработку понадобится длительное время. Используется сервером, чтобы клиент не разорвал соединение из-за превышения времени ожидания. Клиент при получении такого ответа должен сбросить таймер и дожидаться следующей команды в обычном режиме. Появился в WebDAV.

200

ОК
Успешный запрос. Если клиентом были запрошены какие-либо данные, то они находятся в заголовке и/или теле сообщения. Появился в HTTP/1.0.

201

Created
В результате успешного выполнения запроса был создан новый ресурс. Сервер должен указать его местоположение в заголовке Location. Серверу рекомендуется[источник не указан 336 дней] ещё указывать в заголовке характеристики созданного ресурса (например, в поле Content-Type). Если сервер не уверен, что ресурс действительно будет существовать к моменту получения данного сообщения клиентом, то лучше использовать ответ с кодом 202. Появился в HTTP/1.0.

202

Accepted
Запрос был принят на обработку, но она не завершена. Клиенту не обязательно дожидаться окончательной передачи сообщения, так как может быть начат очень долгий процесс. Появился в HTTP/1.0.

203

Non-Authoritative Information
Аналогично ответу 200, но в этом случае передаваемая информация была взята не из первичного источника (резервной копии, другого сервера и т. д.) и поэтому может быть неактуальной. Появился в HTTP/1.1.

204

No Content
Сервер успешно обработал запрос, но в ответе были переданы только заголовки без тела сообщения. Клиент не должен обновлять содержимое документа, но может применить к нему полученные метаданные. Появился в HTTP/1.0.

205

Reset Content
Сервер обязывает клиента сбросить введённые пользователем данные. Тела сообщения сервер при этом не передаёт и документ обновлять не обязательно. Появился в HTTP/1.1.

206

Partial Content
Сервер удачно выполнил частичный GET-запрос, возвратив только часть сообщения. В заголовке Content-Range сервер указывает байтовые диапазоны содержимого. Особое внимание при работе с подобными ответами следует уделить кэшированию. Появился в HTTP/1.1. (подробнее…)

207

Multi-Status
Сервер передаёт результаты выполнения сразу нескольких независимых операций. Они помещаются в само тело сообщения в виде XML-документа с объектом multistatus. Не рекомендуется размещать в этом объекте статусы из серии 1xx из-за бессмысленности и избыточности. Появился в WebDAV.

226

IM Used
Заголовок A-IM от клиента был успешно принят и сервер возвращает содержимое с учётом указанных параметров. Введено в RFC 3229 для дополнения протокола HTTP поддержкой дельта-кодирования.

300

Multiple Choices
По указанному URI существует несколько вариантов предоставления ресурса по типу MIME, по языку или по другим характеристикам. Сервер передаёт с сообщением список альтернатив, давая возможность сделать выбор клиенту автоматически или пользователю. Появился в HTTP/1.0.

301

Moved Permanently
Запрошенный документ был окончательно перенесен на новый URI, указанный в поле Location заголовка. Некоторые клиенты некорректно ведут себя при обработке данного кода. Появился в HTTP/1.0.

302

Found, Moved Temporarily
Запрошенный документ временно доступен по другому URI, указанному в заголовке в поле Location. Этот код может быть использован, например, приуправляемом сервером согласовании содержимого. Некоторые клиенты некорректно ведут себя при обработке данного кода. Введено в HTTP/1.0.

303

See Other
Документ по запрошенному URI нужно запросить по адресу в поле Location заголовка с использованием метода GET несмотря даже на то, что первый запрашивался иным методом. Этот код был введён вместе с 307-ым для избежания неоднозначности, чтобы сервер был уверен, что следующий ресурс будет запрошен методом GET. Например, на веб-странице есть поле ввода текста для быстрого перехода и поиска. После ввода данных браузер делает запрос методом POST, включая в тело сообщения введённый текст. Если обнаружен документ с введённым названием, то сервер отвечает кодом 303, указав в заголовке Location его постоянный адрес. Тогда браузер гарантировано его запросит методом GET для получения содержимого. В противном случае сервер просто вернёт клиенту страницу с результатами поиска. Введено в HTTP/1.1.

304

Not Modified
Сервер возвращает такой код, если клиент запросил документ методом GET, использовал заголовок If-Modified-Since или If-None-Match и документ не изменился с указанного момента. При этом сообщение сервера не должно содержать тела. Появился в HTTP/1.0.

305

Use Proxy
Запрос к запрашиваемому ресурсу должен осуществляться через прокси-сервер, URI которого указан в поле Location заголовка. Данный код ответа могут использовать только исходные HTTP-сервера (не прокси). Введено в HTTP/1.1.

306

(зарезервировано)
использовавшийся раньше код ответа, в настоящий момент зарезервирован. Упомянут в RFC 2616 (обновление HTTP/1.1).

307

Temporary Redirect
Запрашиваемый ресурс на короткое время доступен по другому URI, указанный в поле Location заголовка. Этот код был введён вместе с 303 вместо 302-го для избежания неоднозначности. Введено в RFC 2616 (обновление HTTP/1.1).

400

Bad Request
Сервер обнаружил в запросе клиента синтаксическую ошибку. Появился в HTTP/1.0.

401

Unauthorized
Для доступа к запрашиваемому ресурсу требуется аутентификация. В заголовке ответ должен содержать поле WWW-Authenticate с перечнем условий аутентификации. Клиент может повторить запрос, включив в заголовок сообщения поле Authorization с требуемыми для аутентификации данными.

402

Payment Required
Предполагается использовать в будущем. В настоящий момент не используется. Этот код предусмотрен для платных пользовательских сервисов, а не для хостинговыхкомпаний. Имеется в виду, что эта ошибка не будет выдана хостинговым провайдером в случае просроченной оплаты его услуг. Зарезервирован, начиная с HTTP/1.1.

403

Forbidden
Сервер понял запрос, но он отказывается его выполнять из-за ограничений в доступе для клиента к указанному ресурсу. Если для доступа к ресурсу требуется аутентификация средствами HTTP, то сервер вернёт ответ 401 или 407 при использовании прокси. В противном случае ограничения были заданы администратором сервера или разработчиком веб-приложения и могут быть любыми в зависимости от возможностей используемого программного обеспечения. В любом случае клиенту следует сообщить причины отказа в обработке запроса. Наиболее вероятными причинами ограничения может послужить попытка доступа к системным ресурсам веб-сервера (например, файлам .htaccess или .htpasswd) или к файлам, доступ к которым был закрыт с помощью конфигурационных файлов, требование аутентификации не средствами HTTP, например, для доступа к системе управления содержимым или разделу для зарегистрированных пользователей либо сервер не удовлетворён IP-адресом клиента, например, при блокировках. Появился в HTTP/1.0.

404

Not Found
Самая распространенная ошибка при пользовании Интернетом, основная причина — ошибка в написании адреса Web-страницы. Сервер понял запрос, но не нашёл соответствующего ресурса по указанному URI. Если серверу известно, что по этому адресу был документ, то ему желательно использовать код 410. Ответ 404 может использоваться вместо 403, если требуется тщательно скрыть от посторонних глаз определённые ресурсы. Появился в HTTP/1.0.

405

Method Not Allowed
Указанный клиентом метод нельзя применить к текущему ресурсу. В ответе сервер должен указать доступные методы в заголовке Allow, разделив их запятой. Эту ошибку сервер должен возвращать, если метод ему известен, но он не применим именно к указанному в запросе ресурсу, если же указанный метод не применим на всём сервере, то клиенту нужно вернуть код 501 (Not Implemented). Появился в HTTP/1.1.

406

Not Acceptable
Запрошенный URI не может удовлетворить переданным в заголовке характеристикам. Если метод был не HEAD, то сервер должен вернуть список допустимых характеристик для данного ресурса. Появился в HTTP/1.1.

407

Proxy Authentication Required
Ответ аналогичен коду 401 за исключением того, что аутентификация производится для прокси-сервера. Механизм аналогичен идентификации на исходном сервере. Появился в HTTP/1.1.

408

Request Timeout
Время ожидания сервером передачи от клиента истекло. Клиент может повторить аналогичный предыдущему запрос в любое время. Например, такая ситуация может возникнуть при загрузке на сервер объёмного файла методом POST или PUT. В какой-то момент передачи источник данных перестал отвечать, например, из-за повреждения компакт-диска или потеря связи с другим компьютером в локальной сети. Пока клиент ничего не передаёт, ожидая от него ответа, соединение с сервером держится. Через некоторое время сервер может закрыть соединение со своей стороны, чтобы дать возможность другим клиентам сделать запрос. Этот ответ не возвращается, когда клиент принудительно остановил передачу по команде пользователя или соединение прервалось по каким-то иным причинам, так как ответ уже послать невозможно. Появился в HTTP/1.1.

409

Conflict
Запрос не может быть выполнен из-за конфликтного обращения к ресурсу. Такое возможно, например, когда два клиента пытаются изменить ресурс с помощью метода PUT.Появился в HTTP/1.1.

410

Gone
Такой ответ сервер посылает, если ресурс раньше был по указанному URL, но был удалён и теперь недоступен. Серверу в этом случае неизвестно и местоположение альтернативного документа, например, копии). Если у сервера есть подозрение, что документ в ближайшее время может быть восстановлен, то лучше клиенту передать код 404. Появился в HTTP/1.1.

411

Length Required
Для указанного ресурса клиент должен указать Content-Length в заголовке запроса. Без указания этого поля не стоит делать повторную попытку запроса к серверу по данному URI. Такой ответ естественен для запросов типа POST и PUT. Например, если по указанному URI производится загрузка файлов, а на сервере стоит ограничение на их объём. Тогда разумней будет проверить в самом начале заголовок Content-Length и сразу отказать в загрузке, чем провоцировать бессмысленную нагрузку, разрывая соединение, когда клиент действительно пришлёт слишком объёмное сообщение. Появился в HTTP/1.1.

412

Precondition Failed
Возвращается, если ни одно из условных полей заголовка[неизвестный термин] запроса не было выполнено. Появился в HTTP/1.1.

413

Request Entity Too Large
Возвращается в случае, если сервер отказывается обработать запрос по причине слишком большого размера тела запроса. Сервер может закрыть соединение, чтобы прекратить дальнейшую передачу запроса. Если проблема временная, то рекомендуется в ответ сервера включить заголовок Retry-After с указанием времени, по истечении которого можно повторить аналогичный запрос. Появился в HTTP/1.1.

414

Request-URL Too Long
Сервер не может обработать запрос из-за слишком длинного указанного URL. Такую ошибку можно спровоцировать, например, когда клиент пытается передать длинные параметры через метод GET, а не POST. Появился в HTTP/1.1.

415

Unsupported Media Type
По каким-то причинам сервер отказывается работать с указанным типом данных при данном методе. Появился в HTTP/1.1.

416

Requested Range Not Satisfiabl
В поле Range заголовка запроса был указан диапазон за пределами ресурса и отсутствует поле If-Range. Если клиент передал байтовый диапазон, то сервер может вернуть реальный размер в поле Content-Range заголовка. Данный ответ не следует использовать при передаче типа multipart/byteranges[источник не указан 336 дней]. Введено в RFC 2616 (обновление HTTP/1.1).

417

Expectation Failed
По каким-то причинам сервер не может удовлетворить значению поля Expect заголовка запроса. Введено в RFC 2616 (обновление HTTP/1.1).

422

Unprocessable Entity
Сервер успешно принял запрос, может работать с указанным видом данных, в теле запроса XML-документ имеет верный синтаксис, но имеется какая-то логическая ошибка, из-за которой невозможно произвести операцию над ресурсом. Введено в WebDAV.

423

Locked
Целевой ресурс из запроса заблокирован от применения к нему указанного метода. Введено в WebDAV.

424

Failed Dependency
Реализация текущего запроса может зависеть от успешности выполнения другой операции. Если она не выполнена и из-за этого нельзя выполнить текущий запрос, то сервер вернёт этот код. Введено в WebDAV.

425

Unordered Collection —
Посылается, если клиент послал запрос, обозначив положение в неотсортированной коллекции или используя порядок следования элементов, отличный от серверного[уточнить]. Введено в черновике по WebDAV Advanced Collections Protocol[14].

426

Upgrade Required
Сервер указывает клиенту на необходимость обновить протокол. Заголовок ответа должен содержать правильно сформированные поля Upgrade и Connection. Введено вRFC 2817 для возможности перехода к TLS посредством HTTP.

449

Retry With
Возвращается сервером, если для обработки запроса от клиента поступило недостаточно информации. При этом в заголовок ответа помещается поле Ms-Echo-Request. Введено корпорацией Microsoft для WebDAV. В настоящий момент как минимум используется программой Microsoft Money.

456

Unrecoverable Error
Возвращается сервером, если обработка запроса вызывает некорректируемые сбои в таблицах баз данных[источник не указан 336 дней]. Введено корпорацией Microsoftдля WebDAV.

500

Internal Server Error
Любая внутренняя ошибка сервера, которая не входит в рамки остальных ошибок класса. Появился в HTTP/1.0.

501

Not Implemented
Сервер не поддерживает возможностей, необходимых для обработки запроса. Типичный ответ для случаев, когда сервер не понимает указанный в запросе метод. Если же метод серверу известен, но он не применим к данному ресурсу, то нужно вернуть ответ 405. Появился в HTTP/1.0.

502

Bad Gateway
Сервер, выступая в роли шлюза или прокси-сервера, получил недействительное ответное сообщение от вышестоящего сервера. Появился в HTTP/1.0.

503

Service Unavailable
Сервер временно не имеет возможности обрабатывать запросы по техническим причинам (обслуживание, перегрузка и прочее). В поле Retry-After заголовка сервер может указать время, через которое клиенту рекомендуется повторить запрос. Хотя во время перегрузки очевидным кажется сразу разрывать соединение, эффективней может оказаться установка большого значения поля Retry-After для уменьшения частоты избыточных запросов. Появился в HTTP/1.0.

504

Gateway Timeout
Сервер в роли шлюза или прокси-сервера не дождался ответа от вышестоящего сервера для завершения текущего запроса. Появился в HTTP/1.1.

505

HTTP Version Not Supported
Сервер не поддерживает или отказывается поддерживать указанную в запросе версию протокола HTTP. Появился в HTTP/1.1.

506

Variant Also Negotiates
В результате ошибочной конфигурации выбранный вариант указывает сам на себя, из-за чего процесс связывания прерывается. Экспериментальное. Введено в RFC 2295 для дополнения протокола HTTP технологией Transparent Content Negotiation.

507

Insufficient Storage
Не хватает места для выполнения текущего запроса. Проблема может быть временной. Введено в WebDAV.

509

Bandwidth Limit Exceeded
Используется при превышении веб-площадкой отведённого ей ограничения на потребление трафика. В данном случае владельцу площадки следует обратиться к своему хостинг-провайдеру. В настоящий момент данный код не описан ни в одном RFC и используется только модулем «bw/limited», входящим в панель управления хостингом cPanel, где и был введён.

510

Not Extended
На сервере отсутствует расширение, которое желает использовать клиент. Сервер может дополнительно передать информацию о доступных ему расширениях. Введено в RFC 2774 для дополнения протокола HTTP поддержкой расширений.

Автор: Майкл Болтон

Перевод: портал software-testing.ru

Оригинал статьи: http://www.developsense.com/essays/AReviewOfErrorMessages.html

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

Начальные знания о сообщениях об ошибке

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

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

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

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

При этом не стоит полагаться и на операционную систему. Удивительно, но команды DOS COPY и XCOPY до сих пор не проводят проверку на наличие свободного места на диске перед началом копирования файлов; вместо этого копирование начинается “вслепую” с надеждой на то, что места будет достаточно. Windows ничуть не лучше, эта система тоже не проверяет диск на наличие свободного места перед копированием файлов. Хуже того, если вы одновременно копируете несколько файлов, Windows прерывает процесс копирования после обнаружения первой ошибки и “забывает”, какие файлы были выделены для копирования.

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

 Как выглядит корректно составленное сообщение об ошибке?

Сообщение об ошибке должно:

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

Оно не должно:

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

Хороший пример

Одно из самых лучших сообщений об ошибке, которые я когда-либо видел, выглядело примерно так:

«Система ATS потеряла связь с принтером. Для решения проблемы убедитесь, что принтер включен, и попробуйте запустить печать снова. Если напечатать документ не удается, убедитесь, что оба конца кабеля, соединяющего компьютер с принтером, надежно соединены с устройствами, и попробуйте снова запустить печать. Если и в этом случае проблема не устранена, свяжитесь с Джо Грантом по номеру (212) 555-1212 и сообщите ему, что программа выдает ошибку ATSPR35 в строке 31, модуль PRNFNC»

Это сообщение программы по подбору персонала (называется «Система ATS»), созданной независимым разработчиком для кадрового агентства в 1988. Сообщение выглядит почти так, как я описал выше. Существенным отличием является то, что оно не имеет привычный вид окна Windows, потому что это сообщение из программы DOS. Я упоминаю об этом, потому что это сообщение было составлено во времена, когда объем памяти ограничивался 640 Кб. У пользователей тогда не было большого опыта работы с компьютером, но даже если бы они были экспертами в этой области, все равно сообщение было бы полезным.

Давайте сравним это сообщение с требованиями, предложенными выше:

  • Сообщение совершенно четко идентифицирует программу. Более того, строка заголовка идентифицирует тип ошибки.
  • В сообщении сказано о том, что программа потеряла связь с принтером. В сообщении не говорится «невозможно напечатать», или «LPT1: Ошибка», или любой другой малоинформативный текст, скопированный из операционной системы. Сообщения об ошибке большинства операционных систем очень лаконичны и обычно для пользователя бесполезны. А это сообщение составлено так, что его может понять обычный пользователь.
  • В сообщении пользователю предлагаются действия, которые он способен выполнить, независимо от уровня или опыта владения программой. Здесь не высказываются догадки о причине ошибки. Предложенные действия располагаются от простого к более сложному, а причины – от более вероятных к менее вероятным. Отчасти здесь автору программы повезло – далеко не всегда самые распространенные ошибки проще всего исправить.
  • Программа не предлагает действий, которые будут пустой тратой времени. («Попробуйте перезапустить программу», или еще хуже, «Попробуйте переустановить приложение».)
  • Текст сообщения тщательно составлен. Важен каждый пункт сообщения. Нет бесполезных рекомендаций. Не предлагается искать причину сбоя в другом приложении. Вся информация точная и полезная.
  • Самое главное, в сообщении есть полезная техническая информация и для пользователя, и для сотрудника техподдержки, и для разработчика. Если ошибка содержится в коде, сообщение указывает программисту, где именно следует искать ошибку и тип ошибки. Немаловажный плюс – указание реального имени человека. Приятнее иметь дело с конкретным человеком, чем с абстрактной организацией, наличие имени программиста говорит об ответственности за свою работу.

10 примеров неудачных сообщений об ошибке

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

 

 «Невозможно загрузить список новых групп. Произошла ошибка»

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

К этому сообщению у меня вообще нет комментариев.

yellowexclam

К этому тоже. Хотя оно выглядит не таким грозным как предыдущее.

 

 «Интерфейс передачи сообщений вернул неизвестную ошибку. Если проблема повторяется, перезапустите Outlook»

Вам известно больше, чем вы сообщаете, и вы что-то скрываете? И кстати, как именно может помочь перезапуск Outlook?

 «Переключение из режима Internet Only E-mail Service в режим Corporate or Workgroup E-mail Service может быть несовместимо с существующими приложениями»

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

 

 «Невозможно запустить программу. Возможно, один из компонентов занят или отсутствует. Пожалуйста, проверьте, правильность установки и попробуйте еще раз».

 «Возможно». Компонент занят или отсутствует, или и то и другое? Если компонент используется, то какой именно компонент? Файл? Если так, можно узнать имя файла?

«Действие не может быть выполнено. Действие не может быть выполнено».

Правда? Правда? Какое действие? Какое действие? Что я должен сделать, чтобы устранить проблему? Что я должен сделать, чтобы устранить проблему?

 «Невозможно найти файл cuecard.hlp. Хотите найти файл вручную?»

Нет, не хочу. Я хочу, чтобы вы его нашли.

«Невозможно найти файл cuecard.hlp. Проверьте наличие файла на вашем диске. Если файл не будет найден, переустановите его».

Может, все-таки поищете, нет? Честно говоря, я не помню ситуацию, при которой я получил это сообщение, соответственно не помню и программу, которая его вывела. Тем не менее, я помню, что и тогда мне было непонятно, что мне следует переустановить.

Почему сообщения об ошибках обычно составлены некорректно, и как это можно исправить?

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

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

Программу нужно писать так, чтобы сообщения об ошибках появлялись как можно реже. Чтобы облегчить идентификацию ошибок, включите в вашу программу функцию протоколирования или режим подробной диагностики. Все функции программы, которые могут дать сбой, должны иметь код ошибки, который должен отображаться в сообщении об ошибке. Такие коды помогают выявить причину ошибки, а также облегчают тестирование локализованных версий. Документируйте эти коды ошибок, и в сообщение включите информацию о том, где находится эта документация, чтобы помочь техподдержке. Убедитесь, что в программе есть механизм для идентификации отсутствующих файлов, записей реестра и т. д. Создайте классы и функции обработки ошибок, чтобы получить систематизированные, корректно оформленные сообщения об ошибках – и постоянно используйте их в своей работе в дальнейшем. Проведите анализ кода, проверьте программу с другими разработчиками, чтобы убедиться, что программу легко читать и поддерживать, что в ней нет дефектов и она логически последовательна. Предоставьте тестировщикам инструменты для тестирования или программу, которая позволит просмотреть все сообщения об ошибках в вашей программе.

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

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

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

Обсудить в форуме

Содержание

  • Что такое код ответа HTTP
  • Как проверить код состояния страницы
  • В браузере
  • В Яндекс.Вебмастере
  • В Google Search Console
  • 1* класс кодов (информационные сообщения)
  • 100 Continue
  • 101 Switching Protocols
  • 102 Processing
  • 103 Checkpoint
  • 105 Name Not Resolved
  • 2* класс кодов (успешно обработанные запросы)
  • 200 ОК
  • 201 Created
  • 202 Accepted
  • 203 Non‑Authoritative Information
  • 204 No Content
  • 205 Reset Content
  • 206 Partial Content
  • 207 Multi‑Status
  • 226 IM Used
  • 3* класс кодов (перенаправление на другой адрес)
  • 300 Multiple Choices
  • 301 Moved Permanently
  • 302 Found/Moved 
  • 303 See Other
  • 304 Not Modified
  • 305 Use Proxy
  • 306 Unused
  • 307 Temporary Redirect
  • 308 Resume Incomplete
  • 4* класс кодов (ошибки на стороне клиента)
  • 400 Bad Request
  • 401 Unauthorized
  • 402 Payment Required
  • 403 Forbidden
  • 404 Not Found
  • 405 Method Not Allowed
  • 406 Not Acceptable
  • 407 Proxy Authentication Required
  • 408 Request Timeout
  • 409 Conflict
  • 410 Gone
  • 411 Length Required
  • 412 Precondition Failed
  • 413 Request Entity Too Large
  • 414 Request‑URI Too Long
  • 415 Unsupported Media Type
  • 416 Requested Range Not Satisfiable
  • 417 Expectation Failed
  • 418 I’m a teapot
  • 422 Unprocessable Entity
  • 423 Locked
  • 424 Failed Dependency
  • 425 Unordered Collection
  • 426 Upgrade Required
  • 428 Precondition Required
  • 429 Too Many Requests
  • 431 Request Header Fields Too Large
  • 434 Requested Host Unavailable
  • 444 No Response
  • 449 Retry With
  • 450 Blocked by Windows Parental Controls
  • 451 Unavailable For Legal Reasons
  • 456 Unrecoverable Error
  • 499 Client Closed Request
  • 5* класс кодов (ошибки на стороне сервера)
  • 500 Internal Server Error
  • 501 Not Implemented
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout
  • 505 HTTP Version Not Supported
  • 506 Variant Also Negotiates
  • 507 Insufficient Storage
  • 508 Loop Detected
  • 509 Bandwidth Limit Exceeded
  • 510 Not Extended
  • 511 Network Authentication Required
  • Составили подробный классификатор кодов состояния HTTP. Добавляйте в закладки, чтобы был под рукой, когда понадобится.

    Что такое код ответа HTTP

    Когда посетитель переходит по ссылке на сайт или вбивает её в поисковую строку вручную, отправляется запрос на сервер. Сервер обрабатывает этот запрос и выдаёт ответ — трехзначный цифровой код HTTP от 100 до 510. По коду ответа можно понять реакцию сервера на запрос. 

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

    Как проверить код состояния страницы

    Проверить коды ответа сервера можно вручную с помощью браузера и в панелях веб‑мастеров: Яндекс.Вебмастер и Google Search Console.

    В браузере

    Для примера возьмём Google Chrome.

    1. Откройте панель разработчика в браузере клавишей F12, комбинацией клавиш Ctrl + Shift + I или в меню браузера → «Дополнительные инструменты» → «Инструменты разработчика». Подробнее об этом рассказывали в статье «Как открыть исходный код страницы». 

    2. Переключитесь на вкладку «Сеть» в Инструментах разработчика и обновите страницу: 

    Как посмотреть код ответа сервера в инструментах разработчика в браузере

    Как посмотреть код ответа сервера в инструментах разработчика в браузере

    В Яндекс.Вебмастере

    Откройте инструмент «Проверка ответа сервера» в Вебмастере. Введите URL в специальное поле и нажмите кнопку «Проверить»:

    Как посмотреть код состояния в Вебмастере

    Как посмотреть код состояния в Вебмастере

    Как добавить сайт в Яндекс.Вебмастер и другие сервисы Яндекса

    В Google Search Console

    Чтобы посмотреть код ответа сервера в GSC, перейдите в инструмент проверки URL — он находится в самом верху панели:

    Проверка URL в инструменте GSC

    Проверка URL в инструменте GSC

    Введите ссылку на страницу, которую хотите проверить, и нажмите Enter. В результатах проверки нажмите на «Изучить просканированную страницу» в блоке «URL есть в индексе Google».

    Изучить просканированную страницу в GSC

    Изучить просканированную страницу в GSC

    А затем в открывшемся окне перейдите на вкладку «Подробнее»:

    HTTP код страницы в GSC

    HTTP код страницы в GSC

    Теперь расскажем подробнее про все классы кодов состояния HTTP.

    1* класс кодов (информационные сообщения)

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

    100 Continue

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

    101 Switching Protocols

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

    102 Processing

    Запрос принят — он находится в обработке, и на это понадобится чуть больше времени.

    103 Checkpoint

    Контрольная точка — используется в запросах для возобновления после прерывания запросов POST или PUT.

    POST отправляет данные на сервер, PUT создает новый ресурс или заменяет существующий данными, представленными в теле запроса. 

    Разница между ними в том, что PUT работает без изменений: повторное его применение даёт такой же результат, что и в первый раз, а вот повторный вызов одного и того же метода POST часто меняет данные. 

    Пример — оформленный несколько раз интернет‑заказ. Такое часто происходит как раз по причине неоднократного использования запроса PUT.

    105 Name Not Resolved

    Не удается преобразовать DNS‑адрес сервера — это  означает ошибку в службе DNS. Эта служба преобразует IP‑адреса в знакомые нам доменные имена.

    2* класс кодов (успешно обработанные запросы)

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

    200 ОК

    Все хорошо — HTTP‑запрос успешно обработан (не ошибка).

    201 Created

    Создано — транзакция успешна, сформирован новый ресурс или документ.

    202 Accepted

    Принято — запрос принят, но ещё не обработан.

    203 Non‑Authoritative Information

    Информация не авторитетна — запрос успешно обработан, но передаваемая информация была взята не из первичного источника (данные могут быть устаревшими).

    204 No Content

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

    205 Reset Content

    Сбросить содержимое. Запрос успешно обработан — но нужно сбросить введенные данные. Страницу можно не обновлять.

    206 Partial Content

    Частичное содержимое. Сервер успешно обработал часть GET‑запроса, а другую часть вернул.

    GET — метод для чтения данных с сайта. Он говорит серверу, что клиент хочет прочитать какой‑то документ. 

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

    При работе с подобными ответами следует уделить внимание кэшированию.

    207 Multi‑Status

    Успешно выполнено несколько операций — сервер передал результаты выполнения нескольких независимых операций. Они появятся в виде XML‑документа с объектом multistatus. 

    226 IM Used

    Успешно обработан IM‑заголовок (специальный заголовок, который отправляется клиентом и используется для передачи состояния HTTP).

    3* класс кодов (перенаправление на другой адрес)

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

    300 Multiple Choices

    Множественный выбор — сервер выдает список нескольких возможных вариантов перенаправления (максимум — 5). Можно выбрать один из них.

    301 Moved Permanently

    Окончательно перемещено — страница перемещена на другой URL, который указан в поле Location.

    302 Found/Moved 

    Временно перемещено — страница временно перенесена на другой URL,  который указан в поле Location.

    303 See Other

    Ищите другую страницу — страница не найдена по данному URL, поэтому смотрите страницу по другому URL, используя метод GET.

    304 Not Modified

    Модификаций не было — с момента последнего визита клиента изменений не было.

    305 Use Proxy

    Используйте прокси — запрос к нужному ресурсу можно сделать только через прокси‑сервер, URL которого указан в поле Location заголовка.

    306 Unused

    Зарезервировано. Код в настоящий момент не используется.

    307 Temporary Redirect

    Временное перенаправление — запрашиваемый ресурс временно доступен по другому URL.

    Этот код имеет ту же семантику, что код ответа 302 Found, за исключением того, что агент пользователя не должен изменять используемый метод HTTP: если в первом запросе использовался POST, то во втором запросе также должен использоваться POST.

    308 Resume Incomplete

    Перемещено полностью (навсегда) — запрашиваемая страница была перенесена на новый URL, указанный в поле Location заголовка. Метод запроса (GET/POST) менять не разрешается.

    4* класс кодов (ошибки на стороне клиента)

    Эти коды указывают на ошибки со стороны клиентов. 

    Скриншот страницы с ошибкой 404 с сайта modcloth.com

    Скриншот страницы с ошибкой 404 с сайта modcloth.com

    400 Bad Request

    Неверный запрос — запрос клиента не может быть обработан, так как есть синтаксическая ошибка (возможно, опечатка).

    401 Unauthorized

    Не пройдена авторизация — запрос ещё в обработке, но доступа нет, так как пользователь не авторизован.

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

    402 Payment Required

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

    403 Forbidden

    Запрещено — запрос принят, но не будет обработан, так как у клиента недостаточно прав. Может возникнуть, когда пользователь хочет открыть системные файлы (robots, htaccess) или не прошёл авторизацию.

    404 Not Found

    Не найдено — запрашиваемая страница не обнаружена. Сервер принял запрос, но не нашёл ресурса по указанному URL (возможно, была ошибка в URL или страница была перемещена).

    405 Method Not Allowed

    Метод не разрешён — запрос был сделан методом, который не поддерживается данным ресурсом. Сервер должен предложить доступные методы решения в заголовке Allow.

    406 Not Acceptable

    Некорректный запрос — неподдерживаемый поисковиком формат запроса (поисковый робот не поддерживает кодировку или язык).

    407 Proxy Authentication Required

    Нужно пройти аутентификацию прокси — ответ аналогичен коду 401, только нужно аутентифицировать прокси‑сервер.

    408 Request Timeout

    Тайм‑аут запроса — запрос клиента занял слишком много времени. На каждом сайте существует свое время тайм‑аута — проверьте интернет‑соединение  и просто обновите страницу.

    409 Conflict

    Конфликт (что‑то пошло не так) — запрос не может быть выполнен из‑за конфликтного обращения к ресурсу (несовместимость двух запросов).

    410 Gone

    Недоступно — ресурс раньше был размещён по указанному URL, но сейчас удалён и  недоступен (серверу неизвестно месторасположение).

    411 Length Required

    Добавьте длины — сервер отклоняет отправляемый запрос, так как длина заголовка не определена, и он не находит значение Content‑Length. 

    Нужно исправить заголовки на сервере, и в следующий раз робот сможет проиндексировать страницу.

    412 Precondition Failed

    Предварительное условие не выполнено — стоит проверить правильность HTTP‑заголовков данного запроса.

    413 Request Entity Too Large

    Превышен размер запроса — перелимит максимального размера запроса, принимаемого сервером. Браузеры поддерживают запросы от 2 до 8 килобайт.

    414 Request‑URI Too Long

    Превышена длина запроса — сервер не может обработать запрос из‑за длинного URL. Такая ошибка может возникнуть, например, когда клиент пытается передать чересчур длинные параметры через метод GET, а не POST.

    415 Unsupported Media Type

    Формат не поддерживается —  сервер не может принять запрос, так как  данные подгружаются в некорректном формате, и сервер разрывает соединение.

    416 Requested Range Not Satisfiable

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

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

    417 Expectation Failed

    Ожидания не оправдались — прокси некорректно идентифицировал содержимое поля «Expect: 100‑Continue».

    418 I’m a teapot

    Первоапрельская шутка разработчиков в 1998 году. В расшифровке звучит как «я не приготовлю вам кофе, потому что я чайник». Не используется в работе.

    422 Unprocessable Entity

    Объект не обработан — сервер принял запрос, но в нём  есть логическая ошибка. Стоит посмотреть в сторону семантики сайта.

    423 Locked

    Закрыто — ресурс заблокирован для выбранного HTTP‑метода. Можно перезагрузить роутер и компьютер. А также использовать только статистический IP.

    424 Failed Dependency

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

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

    425 Unordered Collection

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

    426 Upgrade Required

    Нужно обновление — в заголовке ответа нужно корректно сформировать поля Upgrade и Connection. 

    Этот ответ возникает, когда серверу требуется обновление до SSL‑протокола, но клиент не имеет его поддержки.

    428 Precondition Required

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

    429 Too Many Requests

    Слишком много запросов — отправлено слишком много запросов за короткое время. Это может указывать, например, на попытку DDoS‑атаки, для защиты от которой запросы блокируются.

    431 Request Header Fields Too Large

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

    Исправляется это с помощью сокращения заголовков и повторной отправки запроса.

    434 Requested Host Unavailable

    Адрес запрашиваемой страницы недоступен.

    444 No Response

    Нет ответа — код отображается в лог‑файлах, чтобы подтвердить, что сервер никак не отреагировал на запрос пользователя и прервал соединение. Возвращается только сервером nginx.

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

    449 Retry With

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

    450 Blocked by Windows Parental Controls

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

    451 Unavailable For Legal Reasons

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

    456 Unrecoverable Error

    Неустранимая ошибка — при обработке запроса возникла ошибка, которая вызывает некорректируемые сбои в таблицах баз данных.

    499 Client Closed Request

    Запрос закрыт клиентом — нестандартный код, используемый nginx в ситуациях, когда клиент закрыл соединение, пока nginx обрабатывал запрос.

    5* класс кодов (ошибки на стороне сервера)

    Эти коды указывают на ошибки со стороны серверов. 

    При использовании всех методов, кроме HEAD, сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя. И его можно использовать в работе.

    Изображение страницы с ошибкой сайта REG.RU

    Изображение страницы с ошибкой сайта REG.RU

    500 Internal Server Error

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

    Проверяйте, корректно ли указаны директивы в системных файлах (особенно htaccess) и нет ли ошибки прав доступа к файлам. Обратите внимание на ошибки внутри скриптов и их медленную работу.

    501 Not Implemented

    Не выполнено —  код отдается, когда сам сервер не может идентифицировать метод запроса. 

    Сами вы эту ошибку не исправите. Устранить её может только сервер.

    502 Bad Gateway

    Ошибка шлюза — появляется, когда сервер, выступая в роли шлюза или прокси‑сервера, получил ответное сообщение от вышестоящего сервера о несоответствии протоколов.

    Актуально исключительно для прокси и шлюзовых конфигураций.

    503 Service Unavailable

    Временно не доступен — сервер временно не имеет возможности обрабатывать запросы по техническим причинам (обслуживание, перегрузка и прочее). 

    В поле Retry‑After заголовка сервер укажет время, через которое  можно повторить запрос.

    504 Gateway Timeout

    Тайм‑аут шлюза —  сервер, выступая в роли шлюза или прокси‑сервера, не получил ответа от вышестоящего сервера в нужное время.

    Исправить эту ошибку самостоятельно не получится. Здесь дело в прокси, часто — в веб‑сервере. 

    Первым делом просто обновите веб‑страницу. Если это не помогло, нужно почистить DNS‑кэш. Для этого  нажмите горячие клавиши Windows+R и введите команду cmd (Control+пробел). В открывшемся окне укажите команду ipconfig / flushdns и подтвердите её нажатием Enter.

    505 HTTP Version Not Supported

    Сервер не поддерживает версию протокола — отсутствует поддержка текущей версии HTTP‑протокола. Нужно обеспечить клиента и сервер одинаковой версией.

    506 Variant Also Negotiates

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

    507 Insufficient Storage

    Не хватает места для хранения — серверу недостаточно места в хранилище. Нужно либо расчистить место, либо увеличить доступное пространство.

    508 Loop Detected

    Обнаружен цикл — ошибка означает провал запроса и выполняемой операции в целом.

    509 Bandwidth Limit Exceeded

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

    510 Not Extended

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

    511 Network Authentication Required

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

    Читайте о самых распространённых онлайн ошибках. Какие причины их возникновения и как исправить.

    the-most-common-online-errors-and-how-to-fix-them.png

    Введение

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

    Распространенные типы сетевых ошибок при доступе к ресурсам сети «Интернет»

    Большинство известных видов ошибок в сети «Интернет» сопровождаются кодом состояния «HTTP». Обычно пользователи могут наблюдать сообщение об ошибке, содержащее помимо объясняющего текста еще числовое значение формата «4XX» или «5XX» (за числами четыре или пять следуют две дополнительные цифры, например, код ошибки имеет вид «404»).

    И вариант формата «4XX», и «5XX» являются ошибками, но они имеют существенную разницу. Формат «4XX» – это ошибки, возникающие вследствие деятельности клиента, а «5XX» – результат ошибки сервера. Если при обращении к сетевому ресурсу всплывает сообщение с ошибкой в виде «4XX», то, скорее всего, пользователи могут ее самостоятельно исправить.

    Ошибки вида «5XX» – это ошибки сервера, которые означают, что пользователи не оказывали влияния на результат, приведший к возникновению ошибки, и источником сбоя является неработающий сервер, к которому пользователи пытаются получить доступ. Независимо от вида ошибки, связанна ли она с деятельностью пользователей или работоспособностью удаленного сетевого сервера, пользователи могут предпринять несколько шагов, которые могут помочь решить проблему и устранить существующую неисправность.

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

    «400 Bad Request» («ошибка неверного запроса»)

    Каждый раз, когда пользователи пытаются открыть веб-сайт путем набора «URL-адреса» в адресной строке сетевого обозревателя или нажимают на соответствующую ссылку сайта, полученную посредством различных приложений, веб-браузер инициирует запрос и отправляет его на удаленный сервер веб-сайта, к которому пользователи организовывают соответствующее обращение и стараются получить доступ. Ошибка «400» возникает, когда сервер не может полноценно понять и корректно обработать запрос. Такой вид непредвиденной ошибки может произойти, если указанный запрос искажен, неверен, испорчен или поврежден, но, чаще всего, ошибка возникает по довольно простой причине, например, пользователь использовал «URL-адрес» веб-сайта, которого не существует.

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

    Обновите страницу. Нажатие клавиши «F5» обновляет страницу в большинстве браузеров. Если проблема связана с поврежденным запросом, то его повторная отправка иногда может помочь. Процесс не займет много времени и его всегда стоит попробовать. Ошибка «400» часто является временной, и простое обновление способно нередко ее исправить.

    Перепроверьте «URL- адрес». Иногда неверный «URL-адрес», указанный пользователем в адресной строке обозревателя, может вызвать ошибку «400 Bad Request» вместо ошибки «404 Not Found» (о которой мы также поговорим в одном из разделов). Просмотрите и исправьте адрес при необходимости.

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

    Очистите файлы «cookie» и содержимое кэша используемого веб-браузера. Иногда, при обращении к веб-сайту, от сервера возвращается ответ с ошибкой «400», потому что происходит попытка прочесть «cookie» на пользовательском компьютере, которые повреждены или сильно устарели, или, как вариант, браузер кэшировал поврежденную версию страницы, которую пользователь пытается открыть. Своевременная очистка данных кэша и файлов «cookie» может помочь исправить неприятную ошибку.

    «403 Forbidden» (ошибка «запрещено»)

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

    Несмотря на тот факт, что ошибка «403», ограничивающая доступ к удаленному ресурсу, регулируется и управляется настройками сетевого веб-сервера, пользователи могут опробовать несколько шагов для ее исправления.

    Обновите страницу. Нажатие клавиши «F5» во многих популярных обозревателях позволяет мгновенно обновить страницу.

    Повторно проверьте «URL- адрес». Иногда неверно заданный в строке обозревателя «URL-адрес» может вызвать появление ошибки запрета доступа «403 Forbidden». Убедитесь, что «URL-адрес» действительно указывает на страницу, а не на каталог. Большинство веб-сайтов ограничивают доступ к своим внутренним папкам из соображений безопасности, и опечатка в адресе может быть причиной отображения ошибки «403».

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

    «404 Not Found» (ошибка «не найдено»)

    Ошибка «404 Not Found» – самая распространенная ошибка в сети, которая возникает при попытке посетить несуществующую веб-страницу. В основном, данная ошибка подразумевает, что серверу не удалось найти, искомый пользователями, удаленный ресурс. В большинстве случаев, в обозревателе появится сообщение об ошибке «404» после неудачной попытки ввести «URL» искомой страницы или перейти по соответствующей ссылке, которая на сервере абсолютно не представлена. И если пользователи сталкиваются с ошибкой «404», то можно попробовать ее исправить несколькими способами.

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

    Убедитесь в правильности «URL- адреса». Неверно введенные «URL-адреса» (независимо от того, была ли допущена ошибка в процессе набора или веб-страница содержит неверную ссылку) являются наиболее частой причиной отображения в обозревателе сообщения об ошибке «404 Not Found».

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

    «500 Internal Server Error» («внутренняя ошибка сервера»)

    Если пользователь пытается посетить веб-сайт и на странице веб-браузера всплывает сообщение «500 Internal Server Error», это обычно означает, что на сетевом ресурсе, к которому непосредственно происходит обращение, существует определенная неполадка и сервер не может предоставить более конкретную информацию. Проблема относится только к сайту и никак не связана с настройками и функционированием пользовательского веб-браузера, персонального компьютера или задействованным способом подключения к сети «Интернет».

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

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

    Важное замечание. Не пытайтесь перезагрузить страницу, если перед получением данного сообщения об ошибке «500» была предпринята попытка осуществить онлайн-платеж или любой вид денежного перевода. Принудительное обновление страницы может привести к отправке одного и того же платежа дважды. Большинство веб-сайтов обладают встроенным инструментом защиты и должны препятствовать повторному переводу денежных средств, но проблема может возникнуть, если веб-сайт испытывает проблему во время выполнения платежа.

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

    Свяжитесь с администрацией сайта. Если проблема не устранена, попробуйте, при возможности, связаться со службой поддержки веб-сайта, и сообщить им о возникших неполадках.

    «502 Bad Gateway» («ошибка шлюза»)

    Ошибка «502 Bad Gateway» означает, что посещаемый вами сервер пытался получить некоторую информацию с другого сервера, но получил неверный ответ. Причиной могут послужить несколько факторов. Возможно, сервер перегружен или возникли неполадки с сетью между двумя серверами, что носит временный характер, и может быть быстро исправлено. Также, как вариант, могут оказывать влияние на отсутствие доступа неправильные настройки брандмауэра или даже ошибка кодирования. В довольно редких случаях ошибка может возникать из-за проблемы на пользовательском компьютере или сетевом оборудовании. Поэтому стоит попробовать применить несколько шагов для возможного исправления ситуации.

    Обновите страницу после отображения сообщения об ошибке. Как и в предыдущих случаях, воспользуйтесь быстрым способом перезагрузки страницы посредством нажатия в веб-браузере клавиши «F5».

    Проверьте, доступен ли сайт для других пользователей. Посетите сайт, такой как «IsItDownRightNow» или «DownforEveryoneorJustMe», который отслеживает состояние веб-сайтов и проверяет их работоспособность для уточнения данных, испытывают ли другие пользователи трудности с доступом к конкретному ресурсу, или проблемы возникают только локально на пользовательском устройстве.

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

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

    «503 Service Unavailable» (ошибка «сервис недоступен»)

    Ошибка «503 Service Unavailable» означает, что сервер временно не может обработать запрос пользователя. Ошибка может возникать по ряду причин, но наиболее распространенная, из доступного списка вариантов, состоит в том, что сервер перегружен внешними запросами. Отображение данной ошибки на странице веб-браузера после обращения пользователя фактически означает, что с сервером все в порядке, его работоспособность не нарушена и он может обработать ваш запрос, но чрезмерная нагрузка не позволяет этого сделать в данный момент. Подобно всем ошибкам формата «5XX», ошибка «503» происходит на сервере, и, следовательно, с пользовательским компьютером все в порядке, и он не влияет на ее наличие.

    Но несмотря на удаленную форму неисправности, можно попробовать применить несколько способов для устранения ошибки.

    Обновите страницу с сообщением об ошибке. Нажмите на клавишу «F5» и принудительно обновите проблемную страницу (стандартный способ перезагрузки поддерживается многими основными веб-браузерами).

    Проверьте работоспособность ресурса. Перейдите в веб-браузере на сайт проверки состояния удаленных ресурсов, например, «IsItDownRightNow» или «DownforEveryoneorJustMe», и оцените его доступность для других пользователей.

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

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

    Данный материал является частной записью члена сообщества Club.CNews.
    Редакция CNews не несет ответственности за его содержание.

    • D.1.Сообщения об ошибках компилятора.
      • D.1.1. Сообщения о фатальных ошибках.
      • D.1.2. Сообщения об ошибках компилятора.
      • D.1.3. Предупреждающие сообщения.
      • D.1.4. Ограничения компилятора.
    • D.2.Сообщения об ошибках в командной строке.
      • D.2.1. Неисправимые ошибки командной строки.
      • D.2.2. Сообщения об ошибках командной строки.
      • D.2.3. Предупреждающие сообщения командной строки.
        • D.3. Сообщения об ошибках периода выполнения.
      • D.3.1. Исключительные ситуации операций с плавающей точкой.
      • D.3.1. Сообщения об ошибках периода выполнения.
      • D.3.3. Ограничения периода выполнения.
    • D.4. Сообщения об ошибках компановщика.
    • D.5.Сообщения об ошибках утилиты LIB.
    • D.6. Сообщения об ошибках утилиты MAKE.

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

    Компонент                         Раздел
    
    Компилятор Microsoft Quick-C      Раздел D.1, "Сообщения об ошибках
                                      компилятора.
    Командная строка, используемая    Раздел D.2, "Сообщение об ошибках
    для вызова компилятора Quick-C    командной строки".
    Библиотеки исполняющей системы    Раздел D.3, "Сообщения об ошибках
    Microsoft C и другие ситуации     периода выполнения".
    периода выполнения.
    Оверлейный компановщик Microsoft, Раздел D.4, "Сообщения об ошибках
    утилита LINK.                     компановщика".
    Диспетчер библиотек фирмы         Раздел D.5, "Сообщения об ошибках
    Microsoft-утилита LIB             утилиты LIB".
    Утилита поддержки разработки      Раздел D.6, "Сообщения об ошибках
    программ MAKE                     утилиты MAKE".
    

    Обратите внимание, что все ошибочные сообщения компилятора, командной строки, периода выполнения приведены в данном приложении в алфавитном порядке.

    В Разделе D.1.4 вы найдете информацию об ограничениях компилятора, а в Разделе D.3.3-ограничения периода выполнения.

    D.1.Сообщения об ошибках компилятора.

    Сообщения об ошибках, Полученные при сбоях СИ-компилятора, делятся на три категории:

    1.Сообщения о фатальных ошибках.

    2.Сообщения об ошибках компиляции.

    3.Предупреждающие сообщения.

    Сообщения каждой категории даны ниже в пронумерованном порядке, с кратким объяснением каждой ошибки. Чтобы найти требуемое сообщение, сначала определите категорию сообщения, затем найдите соответствующий номер ошибки. Каждое сообщение, сгенерированное в среде Quick-C, появляется в окне ошибок; курсор устанавливается на строке, вызвавшей ошибку (подробности в Разделе 7.3.4). Каждое сообщение об ошибке, сгенерированное во время компиляции с помощью команды QCL, содержит имя файла и номер строки, вызвавшей ошибку.

    Сообщения о фатальных ошибках.

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

    имя файла(строка): fatal error C1xxx: текст сообщения После того, как компилятор высветит сообщение о фатальной ошибке, он завершит выполнения без создания объектного файла и какой-либо проверки на последующие ошибки.

    Сообщения об ошибках компилятора.

    Сообщения об ошибках компилятора индицируют реальные программные ошибки. Данные сообщения выводятся в следующем формате:

    имя файла(строка):error C2xxx:текст сообщения

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

    Предупреждающие сообщения.

    Предупреждающие сообщения носят только информативный характер; они не прерывают процесс компиляции или компановки. Данные сообщения появляются в следующем формате:

    имя файла(строка): warning C4xxx: текст сообщения

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

    D.1.1. Сообщения о фатальных ошибках.

    Следующие сообщения идентифицируют фатальные ошибки. Компилятор не может исправить фатальную ошибку; он прекращает работу после распечатки сообщения об ошибке.

    Номер Сообщение о фатальной ошибке C1000 "Неизвестная фатальная ошибка, Свяжитесь с Техническим сервисом фирмы Microsoft". Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите фирме Microsoft Corporation условия возникновения данной ошиб- ки посредством специальной формы "Product Assistan Request", на обложке данного руководства. C1001 "Внутренняя ошибка компилятора, свяжитесь с Техническим серви- сом фирмы Microsoft". Компилятор обнаружил внутреннее несоответствие. Пожалуйста, со- общите условия возникновения данной ошибке с помощью бланка "Product Assistance Request" на обложке данного руководства. Пожалуйста, включите в ваше сообщение имя файла и номер стро- ки, вызвавшей ошибку; обратите внимание, что "имя файла" отно- носится к внутреннему файлу компилятора, а не к вашему исход- ному файлу. C1002 "Выход за пределы динамической области". Компилятор вышел за пределы динамическогй области памяти. Дан- ная ситуация обычно означает, что ваша программа имеет слишком много символических имен и/или комплексных выражений. Чтобы из- бавиться от данной проблемы, разделите файл на несколько мень- ших исходных файлов, либо разбейте выражения на меньшие подвы- ражения. C1003 "Счетчик ошибок превысил n; компиляция остановлена". Ошибок в программе слишком много, либо они слишком серьезны, чтобы возможно было восстановление, компилятор должен прервать выполнение. C1004 "Неожиданный конец файла (EOF). Данное сообщение появляется, если у вас не достаточно памяти на стандартном дисковом устройстве, чтобы компилятор создал требу- емые временные файлы. Требуемое пространство примерно в 2 раза больше размера исходного файла. Данное сообщение может быть также сгенерировано, если комментарий не имеет закрывающего ограничителя (*/), либо если директиве #if не хватает закры- вающей директивы #endif. C1005 "Строка слишком велика для буфера". Строка в промежуточном файле компилятора переполняет буфер. C1006 "Ошибка записи в промежуточный файл компилятора". Компилятор не может создать промежуточные файлы, используемые в процессе компиляции. К данной ошибке обычно приводят следую- щие ситуации: 1.Слишком мало файлов в строке files = number файла CONFIG.SYS (компилятор требует чтобы число number было не меньше 15). 2.Не хватает памяти на устройстве, содержащем промежуточные файлы компилятора. C1007 "Нераспознанный флаг 'string' в 'option'" string-в опции командной строки option не является корректной опцией. C1009 "Ограничения компилятора, возможно рекурсивно определенное мак- роопределение". Расширение макрокоманды превышает размеры доступной памяти. Проверьте, не было ли рекурсивно-определенных макрокоманд, либо не слишком велик расширяемый текст. C1010 "Ограничения компилятора: макро-расширение слишком большое". Расширение макрокоманды превышает доступную память. C1012 "Неверное вложение скобок-пропущенный 'character' (символ)". Несоответствие скобок в директиве препроцессора; 'character'- -это либо левая, либо правая скобка. C1013 "Невозможно открыть исходный файл 'filename'". Данный файл 'filename' либо не существует, либо не может быть открыт, либо не найден. Удостоверьтесь, что параметры установ- ки среды корректны, и что для файла задано корректное имя марш- рута. C1014 "Слишком много включаемых файлов". Вложение директив #include превышает 10-уровневый предел. C1015 "Невозможно открыть включаемый файл 'filename'". Данный файл либо не существует, либо не может быть открыт, либо не найден. Удостоверьтесь, что параметры неазначений среды за- даны корректно, и что вы определили корректное имя маршрута для данного файла. C1016 "Директиве #if [n]def требуется идертификатор". С директивами #ifdef и #ifndef вы обязательно должны употреб- лять идентификатор. C1017 "Неверное выражение целой константы". Выражение в директиве #if должно вычисляться в константу. C1018 "Неожиданная директива '#elif'". Появление директивы #elif разрешено только внутри директив #if, #ifdef, или #ifdef. C1019 "Неожиданная директива '#else'". Появление директивы #else возможно только внутри директив #if, #ifdef, или #ifndef. C1020 "Неожиданная директива '#endif'" Директива #endif появилась без соответствующей директивы #if, #ifdif, или #ifndef. C1021 "Неверная команда препроцессора 'string'" Символы, следующие за знаком (#) формируют неверную директиву препроцессора. C1022 "Ожидается директива '#endif'". Директива #if, #ifdef или #ifndef не заканчивается директивой #endif. C1026 "Переполнение стэка, пожалуйста, упростите вашу программу." Ваша программа не может быть далее обработана, поскольку па- мять, требуемая для "разбора" программы переполняет стэк ком- пилятора. Чтобы разрешить данную проблему, упростите вашу программу. C1027 "Ограничения компилятора: вложение структур/смесей". Определения структур и смесей вложены более 10 раз. C1028 "Сегмент segment занимает более 64К" В данном сегменте размещены более 64 "дальних" данных. Один мо- дуль может иметь не более 64К "дальних" данных. Чтобы разрешить данную проблему, либо разбейте объяснения на отдельные модули, сократите общий объем используемых данных, либо откомпилируйте вашу программу с помощью Оптимизирующего компилятора Microsoft-C. C1032 "Невозможно открыть файл, содержащий объектный листинг 'filename'". Имеет силу одно из следующих утверждений, касающихся имени фай- ла или имени маршрута: 1.Данное имя не верно. 2.Файл с данным именем не может быть открыт из-за нехватки памяти. 3.Уже существует файл с данным именем и атрибутом "только-чте- ние". C1033 "Невозможно открыть выходной файл на языке ассемблер 'filename'". Одно из условий, рассмотренных в описании ошибки с кодом C1032, привело к невозможности открыть данный файл. C1034 "Невозможно открыть исходный файл 'filename'". Одно из условий, рассмотренных в описании ошибки с кодом C1032, привело к невозможности открыть данный файл. C1035 "Выражение является слишком сложным, пожалуйста упростите". Компилятор не смог сгенерировать код для сложного выражения. Чтобы разрешить данную проблему, разбейте выражение на более простые подвыражения и повторите компиляцию. C1036 "Невозможно открыть файл, содержащий исходный листинг 'filename'". Одно из условий, рассмотренных в описании ошибки с кодом C1032, привело к невозможности открыть данный файл. C1037 "Невозможно открыть объектный файл 'filename'". Одно из условий, рассмотренных в описании ошибки с кодом C1032, привело к невозможности открыть данный файл. C1039 "Невосстанавливаемое переполнение динамической области в треть- ем проходе компилятора": В третьем оптимизирующем проходе компилятор переполнил динами- ческую область и прекратил работу. Попытайтесь повторить компиляцию с включенной опцией Optimiza- tions (в среде программирования Quick-C), либо с опцией /Od (в командной строке QCL), либо попытайтесь отделить функцию, со- держащую строку, вызвавшую ошибку. C1040 "Неожиданный EOF в исходном файле 'filename'". В процессе создания листинга исходного файла, либо исходного/ объектного файла компилятор обнаружил неожиданный конец файла. Данная ошибка произошла, вероятно, если исходный файл был отре- дактирован в процессе компиляции. C1041 "Невозможно открыть промежуточный файл компилятора-больше нет". Компилятор не может создать промежуточный файл, используемый в процессе компиляции, поскольку больше нет логических номеров файлов. Данная ошибка может быть исправлена путем изменения строки files=number в файле CONFIG.SYS, чтобы задать большее число од- новременно открытых файлов (рекомендуется назначить число 20). C1042 "Невозможно открыть промежуточный файл компилятора-нет такого файла или каталога". Компилятор не может создать промежуточные файлы, используемые в процессе компиляции, поскольку в переменной операционный среды TMP задан неправильный каталог, или маршрут. C1043 "Невозможно открыть промежуточный файл компилятора". Компилятор не может создать промежуточные файлы, используемые в процессе компиляции. Точная причина неизвестна. C1044 "Нехватка дисковой памяти для промежуточного файла компилятора" Из-за недостатка памяти компилятор не может создать промежуточ- ный файл, используемый в процессе компиляции. Для исправления данной ситуации освободите место на диске и повторите компиля- цию. C1045 "Переполнение при операции с плавающей точкой". Компилятор получил ошибку при присваивании арифметических конс- тант элементам с плавающей точкой, как в следующем примере: float fp val = 1.0e100; В данном примере константа двойной точности 1.0е100 превышает максимально-допустимое значение для данных с плавющей точкой. C1047 "Слишком много появлений опции 'string'". Данная опция упоминается слишком много раз. Строка 'string' со- держит опцию, вызвавшую ошибку. C1048 "Неизвестная опция 'character' в 'optionstring'". Символ является некорректной буквой для опции 'optionstring'. C1049 "Неверный числовой аргумент 'string'". Вместо string ожидался числовой аргумент. C1050 "Сегмент кода 'segmentname' слишком большой". В процессе компиляции сегмент кода вырос за пределы 36 байтов от 64К. В данном случае используется 36-байтовый заполнитель, поскольку сбой на некоторых платах микропроцессоров 80286 могут вызвать непредсказуемое поведение программ, если среди прочих условий размер кодового сегмента находится в пределах 36 байтов от 64К. C1052 "Слишком много директив #if/#ifdef's". В программе превышено максимальное число уровней вложения ди- #if/#ifdef. C1053 "Размещение данных DGROUP превышает 64К". В стандартном сегменте данных были размещены более 64К перемен- ных. Для программ компактной, средней и большой модели памяти выпол- няйте компиляцию с помощью команды QCL, используя опцию /GT для размещения элементов данных в отдельных сегментах. C1054 "Ограничения компилятора: слишком глубокая вложенность инициа- заторов". Были превышены ограничения компилятора на вложенность инициали- заторов. Предел - от 10 до 15 уровней, в зависимости от комби- нации инициализируемых типов. Чтобы решить данную проблему, для сокращения уровней вложен- ности упростите тип инициализируемых данных, либо после опи- санияия присваивайте первоначальное значение в отдельных опе- раторах. C1056 "Ограничения компилятора: переполнение в процессе макро-расши- рения". Компилятор переполнил внутренний буфер при расширения макрокоманды. C1057 "Неожиданный EOF в макро-расширении; (пропущено ')'?)". Компилятор обнаружил конец исходного файла в процессе сборки аргументов макро-вызова. Обычно, это является результатом опу- щенной закрывающей правой скобки) в макро-вызове, как и в сле- дующем примере: #define print(a) printf(string is(,#a)) main() { print(the quick brown fox; } C1059 "Превышены пределы "ближней" динамической области". При размещении элементов данных в "ближней" динамической обла- сти (стандартный сегмент данных), компилятор вышел за допусти- мые пределы. C1060 "Превышены пределы "дальней" динамической области". При размещении элементов данных в "дальней" динамической облас- ти компилятор вышел за допустимые пределы памяти. Обычно дан- ная ошибка происходит во встроенных в память программах, по причине того, что таблица имен содержит слишком много имен. Чтобы исправить данную ситуацию, попробуйте выполнить компиля- цию с выключенной опцией Debug, либо попытайтесь подключить меньше включаемых файлов. Если такой способ не спасает ситу- ацию, выполните компиляцию программы посредством команды QCL. C1061 "Ограничения компилятора: слишком глубокое вложение блоков". Вложенность блоков в данной прогамме превышает возможности ком- пилятора. Для исправления данной ситуации перепишите программу так, чтобы вложенность блоков была меньшей. C1063 "Ограничения компилятора-переполнение стека компилятора". Ваша программа слишком сложна, поскольку привела к переполнению стека. Упростите вашу программу и повторите компиляцию. 

    D.1.2. Сообщения об ошибках компилятора.

    Сообщения, перечисленные ниже, означают, что ваша программа имеет ошибки. Когда компилятор встречает одну из ошибок, перечисленных в данном разделе, программа продолжает рассматриваться (если возможно), причем продолжают выводиться оставшиеся сообщения об ошибках. Однако, объектный файл не строится.

    Номер Сообщения об ошибках компилятора C2000 "Нераспознанная ошибка. Обратитесь в Технический сервис фирмы Microsoft". Компилятор не может определить тип обнаруженной ошибки. Пожа- луйста, сообщите условие возникновения данной ошибки в фирму Microsoft, воспользовавшись специальным бланком "Product Assis- tance Reguest", находящимся на обложке данного руководства. C2001 "В константе обнаружен символ перехода на новую строку (newline)". Символ перехода на новую строку в символьной или строковой константе употребляется не в корректной форме управляющей последовательности (/n). C2002 "Фактические параметры макрокоманды превышают допустимые пре- делы памяти". Аргументы макро-препроцессора превышабт 256 байтов. C2003 "Требуется идентификатор". Идентификатор для проверки условия в #if не найден. C2004 "Требуется идентификатор". Директива #if вызвала синтаксическую ошибку. C2005 "В директиве #line требуется номер строки". В директиве #line не хватает заданного номера строки. C2006 "Директиве #include требуется имя файла". В директиве #include не хватает спецификации имени файла. C2007 "Синтаксическая ошибка директивы #define". В директиве #define была обнаружена синтаксическая ошибка. C2008 "'character': невозможен в макроопределении". Данный символ был использован в макроопределении некорректно. C2009 "Повторное использование формального параметра 'identifier' макроопределения". Данный идентификатор был дважды использован в списке формальных параметров макроопределения. C2010 "'character': невозможен в формальном списке". Данный символ был некорректно использован в списке формальных параметров макроопределения. C2011 "'identifier': определения слишком велико". Данное макроопределение превышает 256 байтов. C2012 "Пропущено имя, следующее за '<'". В директиве #include не хватает требуемой спецификации имени файла. C2013 "Не хватает знака '>'". В директиве #include пропущена закрывающая угловая скобка (>) C2014 "Команда препроцессора должна начинаться с первого значащего (не пробельного) символа". В директиве препроцессора на той же самой строке появились не пробельные символы перед знаком #. C2015 "Слишком много символов в константе". Символьная константа содержит более одного символа, либо была использована управляющая последовательность. C2016 "Отсутствует закрывающая одинарная кавычка". Символьная константа не была заключена в одинарные кавычки. C2017 "Некорректная управляющая последовательность". Символ или символы, следующие за знаком () не имеют корректной формы для управляющей последовательности. C2018 "Неизвестный символ 'Oxcharacter'". Данное шестнадцатеричное число не соответствует символу. C2019 "Требуется команда препроцессора, обнаружен символ 'character'" Данный символ следует за знаком (#), но не является первой бук- вой директивы препроцессора. C2020 "Неверное восьмеричное число 'character'". Данный символ не является корректной восьмеричной цифрой. C2021 "Число 'number'слишком велико для символа". Число 'number' слишком велико, чтобы представлять символ. C2023 "Деление на нуль". Второй операнд операции деления (/) при вычислении дает нуль. что может привести к непредсказуемым результатам. C2024 "По модулю 0". Второй операнд в остатке операции (%) при вычислении дает нуль, что может привести к непредсказуемым результатам. C2025 "'identifier': переопределение типа enum/struct/union". Данный идентификатор уже был использован в перечислении, струк- туре или тэге смеси. C2026 "'identifier': переопределение числа перечисления ". Данный идентификатор уже был использован в константе перечисле- ния, либо в том же самом типе перечисления, либо в другом типе перечисления в том же самом виде. C2028 "Член структуры/смеси должен находиться внутри структуры/смеси" Члены структуры или смеси должны быть описаны внутри структу- ры или смеси. Данная ошибка может быть вызвана описанием пе- речисления, содержащим описание члена структуры, как в следу- ющем примере: enum a { january, february, int march; /* описание структуры : ** некорректно */ }; C2029 "'identifier': битовые поля разрешены только в структурах". Только структуры могут содержать битовые поля. C2030 "'identifier': переопределение члена структуры/смеси". Данный идентификатор был более одного раза использован в качес- тве члена одной и той же структуры/смеси. C2031 "'identifier': функция не может быть членом структуры или сме- си". Данная функция была описана в качестве члена структуры или смеси. Для исправления данной ошибки воспользуйтесь указателем на функцию. C2032 "'identifier': базовый тип с ключевыми словами near/far/huge не разрешен". Данный член структуры или смеси был описан с ключевыми слова- ми far и near. C2033 "'identifier': к битовым полям нельзя применять оператор кос- венного обращения (*)". Данное битовое поле было описано как указатель (*), что не разрешено. C2034 "'identifier': битовое поле слишком мало для данного количества разрядов". Количество разрядов, заданное в описаний битового поля превы- ша%т количест-о разрядов в данеод базовом т(пе. C2040 "'.'требует имя структуры или смеси". Выражение перед оператором выбора структуры или смеси (.) явля- ется указателем на структуру или смесь, а не структурой или смесью, как требуется. C2041 "Ключевое слово 'enum' некорректно". В описании структуры или смеси появилось ключевое слово 'enum', либо определение типа 'enum' было сформировано некор- ректно. C2042 "ключевые слова signed/unsigned является взаимо-исключающими". Оба ключевых слова signed и unsigned были одновременно исполь- зованы в одном описании, как в следующем примере: unsigned signed int i; C2043 "Некорректный оператор break". Оператор break разрешен только внутри операторов do, for, while или switch. C2044 "Некорректный оператор continue". Оператор continue разрешен только внутри операторо do, for, или while. C2045 "'identifier': повторное определение метки". Данная метка появилась перед более, чем одним оператором в од- ной и той же функции. C2046 "Некорректное ключевое слово case". Ключевое слово case может находиться только внутри оператора switch. C2047 "Некорректное ключевое слово default". Ключевое слово default может находиться только внутри оператора switch. C2048 "Более одного default". Оператор switch содержит более одной метки default. C2050 "Не целое выражение switch". Выражение switch не является целым. C2051 "Выражение case не константное". Выражения case должны быть целыми константами. C2052 "Выражение case не является целым". Выражения case должны быть целыми константами. C2054 "Значение case 'number' уже было использовано". Данное значение case уже было использовано в операторе switch. C2054 "Требуется знак '(' после идентификатора 'identifier'". По контексту требуются скобки после функции 'identifier'. C2055 "Требуется список формальных параметров, а не тип list". В определении функции вместо списка формальных параметров поя- вился тип аргумента list. C2056 "Некорректное выражение". Из-за предыдущей ошибки выражение является некорректным (Пре- дыдущая ошибка могла не вызвать ошибочного сообщения). C2057 "Требуется константное выражение". По контексту требуется константное выражение. C2058 "Константное выражение не является целым". По контексту требуется целое константное выражение. C2059 "Синтаксическая ошибка: 'token'". Данная лексема вызвала синтаксическую ошибку. C2060 "Синтаксическая ошибка: EOF". Был обнаружен неожиданный конец файла, что вызвало синтак- сическую ошибку. Данная ошибка может быть вызвана опущенной зак рывающей скобкой '}' в конце вашей программы. C2061 "Синтаксическая ошибка: идентификатор 'identifier'". Данный идентификатор вызвал синтаксическую ошибку. C2062 "Тип 'type' не требуется". Данный тип был некорректно употреблен. C2063 "'identifier': не является функцией". Данный идентификатор не объявлен как функция, но сделана попы- тка использовать его в качестве функции. C2064 "Данный терм не вычисляется в функцию". Сделана попытка вызова функции с помощью выражения, которое при вычислении не дает указатель функции. C2065 "'identifier': не определен". Данный идентификатор не определен. C2066 "Преобразование к функции некорректно". Объект был преобразован к типу функции. C2067 "Преобразование к типу массива некорректно". Объект был преобразован к типу массива. C2068 "Некорректное приведение типов". Тип, используемый в приведении типов, не является корректным. C2069 "Приведение типа void к типу, не являющемуся void". Тип void был приведен к другому типу. C2070 "Некорректный операнд sizeof". Операнд выражения sizeof не является идентификатором, либо наи- менованием типа. C2071 "'class': неверный класс памяти". Данный класс памяти не может быть использован в таком контекс- те. C2072 "'identifier': инициализация функции". Была сделана попытка инициализации функции. C2073 "'identifier': невозможно инициализировать массив в функции". Была сделана попытка проинициализировать данный массив внутри функции. Массив можно поринициализировать только на внешнем уровне. C2074 "В функции запрещено инициализировать структуру или смесь". Была сделана попытка проинициализировать данную структуру или смесь внутри функции. Структуры и функции могут быть проинициа- лизированы только на внешнем уровне. C2075 "'identifier': инициализация массива требует только фигурных скобок". При инициализации массива были пропущены фигурные скобки {}. C2076 "'identifier': инициализация структуры или смеси требует только фигурных скобок". При инициализации структуры или смеси были пропущены фигурные скобки {}. C2077 "Нецелый инициализатор поля 'identifier'". Была сделана попытка инициализации члена структуры-битового по- ля нецелым значением. C2078 "Слишком много инициализаторов". Количество инициализаторов превышает количество инициализируе- мых объектов. C2079 "'identifier'-неопределенная структура или смесь". Данный идентификатор был описан, как структура или смесь, тип которой не определен. C2082 "Повторное определение формального параметра 'identifier'". Формальный параметр функции был повторно описан в теле функции. C2083 "Массив 'identifier' уже имеет размер". Размерность для данного массива уже была описана. C2084 "Функция 'identifier' уже имеет тело". Данная функция уже была определена. C2085 "'identifier': не в списке формальных параметров". Данный параметр был объявлен в определении функции для несущес- твующего формального параметра. C2086 "'identifier': переопределение". Данный идентификатор был определен более одного раза. C2087 "'identifier': пропущенный описатель". В определении массива с несколькими описателями было опущено значение описателя для размерности, отличной от первой, как в следующем примере: int func(a) char a[10][]; /* некорректно */ { . . . } int func(a) char a[][5]; /* корректно */ { . . . } C2088 "Использование неопределенного идентификатора 'identifier' пе- речисления/структуры/смеси". Данный идентификатор обращается к структуре или смеси, тип ко- торой не определен. C2089 "typedef определяет функцию near/far". Использование ключевых слов near или far в объявлении typedef не согласуется с использованием ключевых слов near или far для объявленного элемента, как в следующем примере. typedef int far FARFUNC(); FARFUNC near *fp; C2090 "Функция возвращает массив". Функция не может возвращать массив (она может возвращать только указатель на массив). C2091 "Функция возвращает функцию". Функция не может возвращать функцию (она может возвращать толь- ко указатель на функцию). C2092 "Элемент массива не может быть функцией". Массивы функций не разрешаются; однако, можно использовать мас- сивы указателй на функции. C2093 "Невозможно инициализировать статические данные или структуры адресами автоматических переменных". C2098 "Не-адресное выражение". Была сделана попытка инициализации элемента данных, не являю- щегося адресным выражением. C2099 "Неконстантное смещение". Инициализатор использовал неконстантное смещение. C2100 "Некорректное использование оператора (*)". Оператор (*) был применен к неуказателю. C2101 "'&' в константе". Оператор (&) не имеет адресного значения в качестве операнда. C2102 "'&' требуется адресное значение". Оператор адресации (&) должен применяться к адресному значению. C2103 "'&' в регистровой переменной". Была сделана попытка взять адрес регистровой переменной. C2104 "'&' в битовом поле". Была сделана попытка взять адрес битового поля. C2105 "'operator' требует адресного значения". Данный оператор не имеет адресного операнда. C2106 "'operator': левый операнд должен быть адресным". Левый операнд данного оператора не является адресным. C2107 "Некорректный индекс, косвенное наименование (*) не разрешено". Описатель был применен к выражению, которое не вычисляется в указатель. C2108 "Не-целый индекс". В качестве описателя массива было использовано не-целое выраже- ние. C2109 "Описатель в не-массиве". Описатель был использован в переменной, которая не является массивом. C2110 "'+': 2 указателя". Была сделана попытка сложить один указатель с другим. C2111 "Указатель + не-целое значение". Была сделана попытка сложить не-целое значение с указателем. C2112 "Некорректное вычитание указателей". Была сделана попытка вычесть указатели, не указывающие на один и тот же тип. C2113"'-': правый операнд-указатель". Правый операнд в операции вычитания (-) является указателем, а левый операнд-нет. C2114 "'operator': указатель слева; требуется целое справа". Левый операнд в данном операторе является указателем; правый операнд должен быть целым значением. C2115 "'identifier': несовместимые типы". Выражение содержит несовместимые типы. C2116 "'operator': неправильный левый (или правый) операнд". Заданный операнд данного оператора не соответствует данному оператору. C2117 "'operator': Некорректно для структуры или смеси". Значение структуры и смеси не разрешено с данным оператором. C2118 "Отрицательный описатель". Значение, определяющее размер массива, -отрицательно. C2119 "'typedefs' оба определяют косвенное наименование (*)". Были использованы одновременно два типа typedef для объявления элемента данных и оба типа typedef имеют косвенное наимено- вание. Например, объявление p в следующем примере-некорректно: typedef int *P INT; typedef short *P SHORT; /* данное объявление некорректно */ P SHORT P INT P; C2120 "'void'-некорректно со всеми типами". Тип void был использован в объявлении с другим типом. C2121 "typedef определяет другое перечисление". Была попытка использовать тип, объявленный в операторе typedef для задания, как типа перечисления, так и другого типа. C2122 "typedef определяет другую структуру". Была сделана попытка использовать тип, объявленный в операторе typedef, для задания как типа структуры, так и другого типа. C2123 "typedef определяет другую смесь". Была сделана попытка использовать тип, объявленный в операторе typedef, для задания как типа смеси, так и другого типа. C2125 "'idetifier': память, занятая данными, превышает 64К": Данный элемент данных превышает предельный размер 64К. C2126 "'identifier': данные типа automatic превышают размер 32К". Память, занятая локальными переменными функции, превышает зада- нный предел. C2127 "Память, занятая параметрами, превышает 32К". Память, требуемая для парметров функции превышает предел 32К. C2129 "Статическая функция 'identifier' не найдена". Была сделана ссылка на статическую функцию, которая никогда не была определена. C2130 "#line требуется строка, содержащая имя файла". В директиве #line было опущено имя файла. C2131 "Атрибуты near/far/huge заданы более одного раза". Ключевые слова near и far были применены к элементу данных бо- лее одного раза, как в следующем примере: typedef int near NINT; NINT far a; /* некорректно */ C2132 "Синтаксическая ошибка: неожиданный идентификатор". Идентификатор появлился в синтаксически некорректном формате. C2133 "Массив 'identifier': неизвестный размер" Была сделана попытка описать массив с неназначенным размером, как в следующем примере: int mat add(array1) int array1[]; /* корректно */ { int array2[]; /* некорректно */ . . . } C2134 "'identifier': структура или смесь слишком велики". Размер структуры или смеси превышает предел, установленный ком- пилятором (232 байтов). C2135 "Пропущен знак ')' в макро-расширении". В обращении к макрокоманде с аргументами была опущена закрыва- ющая скобка. C2137 "Пустая символьная константа". Была использована некорректная пустая символьная константа (' '). C2138 "Несоответствие закрывающей границы комментария '/*'". Компилятор обнаружил открывающий ограничитель комментария (/*) без соответствующего закрывающего ограничителя (*/). Данная ошибка может возникнуть из-за попытки использования не- корректных вложенных коментариев. C2139 "Тип, за которым следует 'type', некорректен". Некорректная комбинация типов, как в следующем примере: long char a; C2140 "Тип аргумента не может быть функцией, возвращающей ...". Функция была объявлена, как формальный параметр другой функ- ции, как в следующем примере: int funcl (a) int a(); /* некорректно */ C2141 "Для константы перечисления значение превышает допустимые пре- делы". Константа перечисления имеет значение, превышающее допустимые пределы для типа int. C2142 "Для многоточия требуется три точки". Компилятор обнаружил лексему, содержащую две точки (..) и пред- C2143 "Синтаксическая ошибка: недостает лексемы 'token1' перед лексе- мой 'token2'". Компилятор ожидает появления перед token2-token1. Данное сооб- щение может появиться, если пропущена требуемая закрывающая фи- гурная скобка (}), правая скобка ()) либо точка с запятой (;). C2144 "Синтаксическая ошибка: недостает лексемы 'token' перед типом 'type'". Компилятор требует наличия данной лексемы перед данным типом. Данное сообщение может появиться пре пропущенной закрывающей фигурной скобке (}), правой скобке ()), или точке с запятой (;). C2145 "Синтаксическая ошибка: перед идентификатором не хватает лексе- мы 'token'". Компилятор требует наличия перед идентификатором данной лексе- мы. Данное сообщение может появиться при пропущенной точке с запятой (;) в последнем объявлении блока. C2146 "Синтаксическая ошибка: перед идентификатором 'identifier' не хватает лексемы 'token'". Компилятор требует наличия данной лексемы перед данным иденти- фикатором. C2147 "Массив: неизвестный размер". Сделана попытка увеличить индекс, либо указатель на массив, ба- зовый тип которого еще не объявлен. C2148 "Слишком большой массив". Массив превышает максимально-допустимый размер (232 байта). C2149 "'identifier': данное битовое поле не может иметь нулевую шири- ну". Битовое поле с данным именем имеет нулевую ширину. Нулевой раз- мер разрешается иметь только неименованным битовым полям. C2150"'identifier': битовое поле должно иметь тип int, signed int или unsigned int. Стандарт ANSI C требует, чтобы битовые поля имели типы int, signed int или unsigned int. Данное сообщение может появиться только при компиляции с опцией /Za. C2151 "Задано более одного атрибута cdecl/fortran/pascal". Было задано более одного ключевого слова, определяющего согла- щения о вызове функций. C2152 "'identifier': указатели на функции с различными атрибутами". Была сделана попытка присвоить указатель на функцию, объявлен- ную с одними соглашениями о связях (cdecl, fortran или pascal)- -указателю на функцию, объявленную с другими соглашениями о связях. C2153 "Шестнадцатеричные константы должны иметь по крайней мере одну шестнадцатеричную цифру". Ox или OX-являются некорректными шестнадцатеричными константа- ми. За "x" или "X" должна следовать хотя бы одна шестнадца- теричная цифра. C2154 "'name': не относится к сегменту". Имя функции name было первым идентификатором, заданным в аргу- ментном списке прагмы alloc_text, и уже определено как какое- -либо имя, отличное от имени сегмента. C2155 "Имя 'name': уже имеется в сегменте". Имя функции name появляется более, чем в одной прагме alloc_ text. C2156 "Прагма должна быть на внешнем уровне". Некоторые прагмы должны быть определены на глобальном уровне, вне тела функции, а одна из таких прагм оказалась внутри фун- кции. C2157 "'name': перед использованием в списке прагмы данное имя долж- но быть описано". Данное имя функции из списка функций прагмы alloc_text не было описано перед включением в список. C2158 "'name': является функцией". Имя name было задано в списке переменных прагмы same_seg, но ранее было объявлено, как функция. C2159 "Определено более одного класса памяти". В описании было задано более одного класса памяти, как в сле- дующем примере: extern static int i; C2160 "## не может встретиться в начале макро-определения". Макро-определение начинается с оператора подстановки лексем, как в следующем примере: #define mac(a,b) ##a... C2161 "## не может находиться в конце макро-определения". Макро-определение заканчивается оператором подстановки лексем (##). C2162 "Требуется формальный параметр макрокоманды". Лексема, следующая за оператором (#), не является именем фор- мального параметра, как в следующем примере: #Define print(a) printf(#b) C2163"'string': отсутствует, как intrinsic". Функция, определенная в списке функций для прагмы intrinsic или function, не является одной из имеющихся в форме intrinsic фун- кций. C2165 "'keyword': невозможно изменить указатели на данные". Были некорректно использованы ключевые слова fortran, pascal или cdecl для модификации указателя на данные, как в следующем примере: char pascal *p; C2166 "Значение определяет объект, относящийся к классу памяти 'const'". Была сделана попытка присвоить значение элементу данных, объяв- ленному с классом памяти const. C2167 "'name': слишком много фактических параметров для intrinsic. Ссылка на имя intrinsic function содержит слишком много факти- ческих параметров. C2168 "'name': слишком мало фактических параметров для intrinsic". Ссылка на имя содержит слишком мало фактических параметров. C2169 "'name': является intrinsic оно не может быть определено ". Была сделана попытка задать определение для функции, уже описа- нной, как intrinsic. C2171 "'operator': неверный операнд". Данный унарный оператор был использован с операндом некоррект- ного типа, как в следующем примере: int (*fp)(); double d, d1; . . . fp++; d=~d1 C2172 "'function': фактически не указатель, параметр номер'number'. Была сделана попытка передать аргумент, не являющийся указате- лем, функции, требующей указатель. Данный номер указывает, ка- кой аргумент ошибочен. C2173 "'function': фактически не указатель, параметр 'number': спи- сок параметров 'number'". Была сделана попытка передать аргумент, не являющийся указате- лем, функции, требующей указатель. Данная ошибка может произой- ти в вызовах, возвращающих указатель на функцию. Первый номер указывает, какой аргумент вызвал ошибку; второй номер показы- вает, какой список аргументов содержит неверный аргумент. C2174 "'function': фактически имеет тип void: параметр 'number', спи- сок параметров 'number'". Была сделана попытка передать аргумент типа void функции. Фор- мальные параметры и аргументы функции не могут иметь тип void; однако, они могут иметь тип void* (указатель на void). Данная ошибка происходит в вызовах, возвращающих указатель на функцию. Первый номер показывает, какой аргумент вызвал ошибку; второй номер показывает, какой список аргументов содержит неправильный аргумент. C2175 "'function': неразрешенная внешняя ссылка". Данная функция неопределена в исходном файле, либо встроена в среду программирования QUICK-C, либо находится в библиотеке QUICK, если она загружена. Данная ошибка возникает только в одно-модульных, встроенных в среду Quick-C программах. Чтобы разрешить данную проблему, либо определите функцию в исходном файле, либо загрузите библиотеку QUICK,содержащую данную функцию, либо (если функция содержится в стандартной библиотеке СИ-функций), создайте для программы программный список. C2177 "Константа слишком велика". Информация была потеряна, поскольку константа слишком велика, чтобы заменить тип, которому она присваевается. (1) 

    D.1.3. Предупреждающие сообщения.

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

    Номер Предупреждающее сообщение C4000 "Нераспознанное предупреждение, свяжитесь с техническим сер- висом фирмы Microsoft". Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите условия возникновения данной ошибке фирме Microsoft Corpora- tion, воспользовавшись бланком "Product Assistant Request", находящимся в конце данного руководства. C4001 "Макрокоманда 'identifier'требует параметров". Данный идентификатор был определен, как макрокоманда, имеющая один или более аргументов, но используется в программе без ар- гументов. (1). C4002 "Слишком много фактических параметров для макрокоманды 'identi- fier'". Число фактических аргументов, употребляемых с данным идентифи- катором, больше, чем число формальных параметров, заданных в макроопределении данного идентификатора. (1). C4003 "Не достаточно фактических параметров для макрокоманды 'identifier'". Число фактических аргументов, употребляемых с данным идентифи- катором, меньше, чем число формальных параметров, заданных в макроопределении данного идентификатора. (1). C4004 "Не хватает закрывающей скобки после 'defined'". После фразы #if defined пропущена закрывающая скобка. (1). C4005 "'identifier': повторное определение". Данный идентификатор был повторно определен. (1). C4006 "Директиве #indef требуется идентификатор". В директиве #indef задан идентификатор, определение которого отсутствет. (1). C4009 "Строка слишком велика, хвостовые символы отсекаются". Размер строки превышает предел, установленный компилятором. Для исправления данной ситуации разбейте строку на две или бо- лее подстроки. (1). C4011 "Идентификатор усечен до 'identifier'". Принимаются только первые 31 символ идентификатора. (1). C4014 "'identifier': битовое поле должно иметь тип unsigned. Данное битовое поле не было описано с типом unsigned. Битовые поля должны быть описаны, как целые без знака. Компилятор со- ответственно конвертирует данное битовое поле. (1). C4014 "'identifier': битовое поле должно иметь целый тип". Данное битовое поле было описано, не как целое. Битовые поля должны быть описаны, как целые без знака. Было применено пре- образование. (1). C4016 "'identifier': нет типа, возвращаемого функцией". Данная функция еще не была описана либо определена, поэтому тип возвращаемого значения неизвестен. Подразумевается стандартный тип (int). (2). C4017 "Приведение целого выражения к 'дальнему' указателю". Дальние указатели содержат полные адреса сегментов. На процес- соре 8086/8088 приведение целого (int) значения к "дальнему" указателю может создать адрес с бессмысленным значением сегмен- та. (1). C4020 "Слишком много фактических параметров". Число аргументов, определенных в вызове функции, больше числа формальных аргументов, заданных в списке аргументов определения функции. (1). C4021 "Слишком мало фактических параметров". Число аргументов, заданных в вызове функции, меньше числа фор- мальных параметров, определенных в списке аргументов определе- ния функции. (1). C4022 "Несоответствие указателей: параметр n". Тип указателя данного параметра отличен от типа указателя, за- данного в списке аргументов определения функции. (1). C4024 "Различные типы: параметр n". Тип данного параметра функции не согласуется с типом, заданным в списке аргументов определения функции. (1). C4025 "Описание функции задает переменный список аргументов". Список типов аргументов определения функции заканчивается запя- той, за которой следует многоточие, что означает, что функция может принимать переменное число аргументов, но для функции не были описаны формальные параметры. (1). C4026 "Функция была описана со списком формальных параметров". Функция была описана, как принимающая аргументы, но в определе- нии функции не задано формальных параметров. (1). C4027 "Функция была описана без списка формальных параметров". Функция была описана, как не принимающая аргументов (список типов аргументов состоит из слова void), но в определении функ- ции заданы формальные параметры, либо в вызове функции заданы фактические параметры. (1). C4028 "Отличается описание параметра n". Тип данного параметра не согласуется с соответствующим типом в списке типов аргументов, либо с соответствующим формальным па- раметром. (1). C4029 "Описание списка параметров отлично от определения": Список типов аргументов, заданный в описании функции, не со- гласуется с типами формальных параметров, заданных в опреде- лении функции. (1). C4030 "Первый список параметров длиннее второго". Функция была описана более одного раза, причем с различными списками типов аргументов. (1). C4031 "Второй список параметров длиннее, чем первый". Функция была описана более одного раза, причем с различными списками типов аргументов. (1). C4032 "Неименованная структура/смесь в качестве параметра". Тип структуры или смеси был передан как неименованный аргумент, то есть описание формального параметра не может использовать имя и должно описать тип. (1). C4033 "Функция должна возвращать значение". Если функция не описана, как void, она должна возвращать зна- чение. (2). C4034 "Оператор sizeof возвратил 0". Оператор sizeof был применен к операнду, причем в результате был получен 0. (1). C4035 "'identifier': нет возвращаемого значения". Функция описана, как возвращающая значение, но не делает этого. (2). C4036 "Не ожидаемый список формальных параметров". Список формальных параметров был задан в описании функции. Список формальных параметров игнорируется. (1). C4037 "'identifier': формальные параметры игнорируются". В описании функции не найдено перед описанием формальных параметров ни класса памяти, ни наименование типа, как в сле- дующем примере: int * f(a,b,c); Формальные параметры игнорируются. (1). C4038 "'identifier':формальный параметр имеет некорректный класс па- мяти". Данный формальный параметр был описан с классом памяти, от- личным от auto или register. (1). C4039 "'identifier': функция используется в качестве аргумента" Формальный параметр функции был описан, как функция, что не- корректно.Формальный параметр будет преобразован в указатель функции (1). C4040 "Ключевое слово near/far/ в идентификаторе 'identifier' игнори- руется". Ключевые слова near или far не оказывают никакого действия на данный идентификатор и потому игнорируются.(1). C4041 "Формальный параметр 'identifier' переопределен". Данный формальный параметр был в теле функции определен повтор- но, сделав соответствующий фактический параметр для функции не- доступным. (1). C4042 "'identifier' имеет не корректный класс памяти". Заданный класс памяти не может быть использован в данном конте- ксте (например, параметрам функции не может быть присвоен класс extern). Для данного контекста использован вместо некорректного стандартный класс памяти. (1). C4043 "'identifier': тип void изменен на int". Элемент данных, отличный от функции, был описан с типом void. (1). C4045 "'identifier': массив переполнен". Для данного массива было задано слишком много инициализаторов. Лишние инициализаторы будут игнорированы. (1). C4046 "Знак '&' в функции/массиве игнорируется". Была сделана попытка применить оператор адресации (&) к иден- тификатору, обозначающему функцию или массив. (1). C4047 "'operator': различные уровни косвенного наименования". Данную ситуацию иллюстрирует следующий пример: char **p; char *q; . . . p=q; C4048 "Массив описан с помощью различных описателей". Массив был описан дважды с различными размерами. Используется большой размер. (1). C4049"'operator': косвенное наименование применяется к различным ти- пам". Оператор косвенного наименования (*) был использован в выраже- нии для доступа к значениям различных типов. (1). C4051 "Преобразование данных". В выражении два элемента данных имеют различные типы, что при- ведет к преобразованию данных к одному типу. (2). C4052 "Различные типы enum". В выражении были использованы два различных типа enum. (1). C4053 "По крайней мере один операнд void" Выражение с типом void было использовано в качестве операнда. (1). C4056 "Переполнение в константной арифметике". Результат операции превышает 0x7FFFFFFF. (1). C4057 "Переполнение при перемножении констант". Результат операции превышает 0x7FFFFFFF. (1). C4058 "Взят адрес переменной фрейма, DS!=SS". Программа была скомпилирована со стандартным сегментом данных (DS), не равным стэковому сегменту (SS), программа пытается об- ратиться к переменной фрейма посредством ближнего указателя.(1) C4059 "В результате преобразования адрес сегмента потерян". Преобразование "дальнего" указателя (полного адреса сегмента) к "ближнему" указателю (смещение) привело к потере адреса сегмен- та. (1). C4060 "Преобразование 'длинного' адреса в 'короткий' адрес". Преобразование длинного адреса (32-разрядного указателя) в ко- роткий адрес (16-разрядного указателя) привело к потере адреса сегмента. (1). C4061 "long/short несоответствие в аргументе: применено преобразо- вание". Базовые типы действительных и формальных параметров функции различны. Фактический параметр преобразовывается к типу фор- мального параметра. (1) C4063 "'identifier': функция слишком велика для шага оптимизации". Данная функция не была оптимизирована, поскольку для этого недостаточно памяти. Чтобы исправить данную ситуацию, сократи- те размер функции путем разделения ее на две или более меньших функций. (0). C4066 "Таблица локальных имен переполнена-некоторые локальные имена могут быть пропущены в списке". Генератор листинга вышел за пределы динамической области, отве- денной под локальные переменные, поэтому исходный листинг может не включать в себя полную таблицу имен для всех локальных пере- менных C4067 "За директивой 'directive' следуют непонятные символы-требует- ся символ перехода на следующю строку". За директивой препроцессора следуют лишние символы, как в следующем примере: #endif NO_EXT_KEYS Это принимается в некоторых версиях компилятора Microsoft C, исключая версию 1.0 Microsoft Quick C. (1). C4068 "Неизвестная прагма". Компилятор не смог распознать прагму и игнорировал ее. (1). C4069 "Преобразование ближнего указателя к длинному целому". Ближний указатель был преобразован к длинному целому, что за- полнило старшие разряды текущим значением сегмента данных, не равным нулю. (1). C4071 "'identifier': прототип функции не задан". Данная функция была вызвана компилятором перед тем, как компи- лятор обработал соответствующий прототип функции. (3). C4072 "Недостаточно памяти для обработки отладочной информации". Вы скомпилировали программу с опцией /Zi, но для создания со- ответствующей отладочной информации недостаточно памяти. (1). C4073 "Вложенность слишком глубока, дальнейшая вложенность во время отладки игнорируется". Описания появились на уровне вложенности, большем 13. В ре- зультате, все описания будут восприниматься как бы на одном уровне. (1). C4074 "Было использовано нестандартное расширение-'extension'". Было использовано данное нестандартное расширение в то время, как опция Language Extension в диалоговой рамке Compile была выключена, либо опция /Ze не действовала. Данные расширения да- ны в Разделе 8.1.4.6. "Использование расширений языка СИ фирмы Microsoft: Опция Language Extension". (если включена опция /Za, данная ситуация дает ошибку). (3). C4075 "Размер выражения в операторе switch или константа в операторе case имеют слишком большой размер-преобразуются к типу int". Значение, появляющееся в операторах switch или case, больше ти- па int. Компилятор преобразует данное некорректное значение в тип int. (1). C4076 "'type': может быть использовано только с целыми типами". Модификатор типа signed или unsigned был применен к не целому типу, как в следующем примере: unsigned double b; C4077 "Неизвестная опция прагмы check_stack". Со старой формой прагмы check_stack была задана неизвестная опция, как в следующем примере: #pragma check_stack yes В старой форме прагмы check_stack аргумент прагмы должен быть пустым + или -. C4079 "Неожиданный символ 'character'". В аргументном списке прагмы был найден неожиданный разделитель 'character'". C4080 "Пропущено имя сегмента". В первом аргументе аргументного списка прагмы alloc_text про- пущено имя сегмента. Это случается, если первая лексема в ар- гументном списке не является идентификатором. C4082 "Требуется идентификатор". В списке аргументов прагмы пропущен идентификатор. C4083 "Пропущено'('". В аргументном списке прагмы пропущена открывающая левая скобка, как в следующем примере: #pragma check_pointer on) C4084 "Требуется ключевое слово pragma". Лексема, следующая за ключевым словом pragma, не является иден- тификатором, как в следующем примере: #pragma (on) C4085 "Требуется [on/off] Для новой формы прагмы check_stack был задан некорректный аргу- мент, как в следующем примере: #pragma check_stack (yes) C4087 "'name': описана с пустым списком параметров". Данная функция была описана, как не принимающая параметров, в то время как вызов функции определяет фактические параметры, как в следующем примере: int fl(void); . . . fl(10); C4090 "Различные атрибуты 'const'". Указатель на элемент данных, описанный, как const, был пере- дан функции, соответствующий формальный параметр которой явля- ется указателем на элемент данных, не являющийся const. Это значит, что данный элемент данных может быть незаметно изме- нен, как в следующем примере: const char *p = "ascde"; int str(char *s); . . . str(p); C4091 "Не описано никаких имен". Компилятор обнаружил пустое описание, как в следующем примере (2): int; C4092 "Описание перечисления/структуры/смеси не имеет имени". Компилятор обнаружил пустое описание, использующее не имеющую соответствующего тэга структуру, смесь или перечисление, как в следующем примере: struct { . . . }; C4093 "Некорректный символ перехода на новую строку в символьной кон- танте в не действующем коде". Константное выражение в директиве препроцессора #if, #ifdef или #ifndef вычисляется в 0, что делает соответствующий код неактив ным, причем символ перехода на новую строку появляется в данном не активном коде между соответствующими одиночными или двойными кавычками. C4095 "Слишком много аргументов для прагмы". В прагме, имеющей только один аргумент, появляется более одного аргумента. C4096 "Элемент типа huge трактуется, как far". Поскольку компилятор Microsoft Quick-C не поддерживает ключевое слово huge, элемент данных трактуется, как описанный с ключе- вым словом far. Если элемент данных или функция должны все же иметь тип huge, перекомпилируйте программу с помощью Оптимизиру ющего компилятора Microsoft C. C4097 "В строке встретился символ 'hex-character', не относящийся к коду ASCII". Данный не ASCII-символ был использован в данной символьной строке. 

    D.1.4. Ограничения компилятора.

    Для работы с компилятором Microsoft Quick-C вам нужно иметь достаточное количество памяти для обработки временных файлов, используемых для обработки. Требуется память приблизительно в два раза большая, чем размер исходного файла.

    В таблице D.1 приводятся ограничения,накладываемые СИ-компиля- тором. Если ваша программа превышает один из заданных пределов, вас информирует об этом сообщение об ошибке.

     Таблица D.1. Ограничения СИ-компилятора. Элемент программы Описание Ограничения Строковые литералы Максимальная длина строки, 512 байтов включающая нулевое оконча- ние (). Константы Максимальный размер констан- ты зависит от ее типа; смот- рите "Справочное руководство по языку СИ". Идентификаторы Максимальная длина идентифи- 31 байт (дополни- катора тельные символы не воспринимают- ся). Описания Максимальный уровень вло- 10 уровней женности для определений структуры или смеси. Директивы препроцес- Максимальный размер макро- 512 байтов. сора определения. Максимальное количество 8 аргументов фактических параметров в макроопределении. Максимальная длина реально- 256 байтов го аргумента препроцессора. Максимальный уровень вложен- 32 уровня ности директив #if, #ifdef, #ifndef. Максимальный уровень вложен- 10 уровней ности для подключаемых фай- лов. 

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

    D.2.Сообщения об ошибках в командной строке.

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

    command line fatal error D1xxx: messagetext Fatal error (Фатальная ошибка командной строки D1xxx: текст сообщения Фатальная ошибка) command line error D2xxx: messagetext Error (Ошибка командной строки D2xxx: текст сообщения Ошибка) command line warning D4xxx: messagetext Warning (Предупреждение командной строки D4xxx: текст сообщения Предупреждение). 

    Если возможно, компилятор продолжает работу, распечатывая предупреждающее сообщение. В некоторых случаях ошибки командной строки являются неисправимыми и компилятор прекращает работу. Сообщения, приведенные в разделах D.2.1-D.2.3 описывают ошибки командной строки.

    D.2.1. Неисправимые ошибки командной строки.

    Следующие сообщения описывают фатальные ошибки. Драйвер компилятора не может восстановить работу после фатальной ошибки; он прекращает работу после распечатки сообщения.

    Номер Сообщение о фатальной ошибке в командной строке D1000 Неизвестная фтатальная ошибка командной строки. Свяжитесь с тех нической службой фирмы Microsoft. Компилятор обнаружил нераспоз нанную неисправимую ошибку. Пожалуйста, сообщите условия возникновения данной ошибки в фир- му Microsoft Corporation с помощью формы Product Assistance Request, находящейся в конце данного руководства. D1001 "Невозможно выполнить 'filename'". Компилятор не может найти данный файл в текущем рабочем катало- ге, либо в других каталогах, определяемых посредством перемен- ной PATH. D1002 "Слишком много открытых файлов, невозможно переадресовать 'filename'". Больше нет файлов, чтобы переадресовать вывод опции /P в файл. Попробуйте изменить ваш файл CONFIG.SYS и увеличьте значение num в строке files=num (если num меньше 20). 

    D.2.2. Сообщения об ошибках командной строки.

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

    Номер Сообщение об ошибках командной строки D2000 "Нераспознанная ошибка командной строки, обратитесь в техничес- кий сервис фирмы Microsoft". Компилятор обнаружил неизвестную ошибку. Пожалуйста, сообщите условия возникновения данной ошибки фирме Microsoft Corporati- on, используя бланк "Product assistance Request", находяцийся в конце данного руководства. D2001 "Слишком много имен определены с -D". Слишком много символических констант были определены с помощью опции /D командной строки. Обычный предел определений на командной строке 16; если вы ис- пользуете опции /U или /u-предел увеличивается до 20. D2002 "Предварительно определенная модель была отменена". Были определены две различные модели памяти; используется мо- дель, заданная на командной строке позже. D2003 "Пропущено имя исходного файла". Вы не задали имя компилируемого исходного файла. D2007 "Неверно задана опция, следует заменить 'string1' на 'string2'". Данная опция была задана более одного раза с конфликтующими ар- гументами string1 и string2. D2008 "Слишком много флажков опции 'string'". С заданной опцией было определено слишком много букв (например, с опцией /O). D2009 "Неизвестный символ опции 'option string'". Одна из букв данной опции нераспознана. D2010 "Неизвестная опция плавающей точки". Данная опция плавающей точки ( опция /FP) не является коррект- ной. D2011 "Разрешена только одна опция плавающей точки". На командной строке вы задали более одной опции плавающей точ- ки (/FP). D2012 "На командной строке слишком много опций компановщика". Вы сделали попытку задать на командной строке более 128 отдель- ных опций и объектных файлов для компановщика. D2015 "Ассемблерные файлы не обрабатываются". Вы задали на командной строке имя файла с расширением .ASM. Поскольку компилятор не может автоматически вызывать Макроас- семблер (MASM), он не может ассемлировать данные файлы. D2018 "Невозможно открыть файл компановщика cmd". Файл соответствий, передающий компановщику имена объектных фай- лов и опции, не может быть открыт. Данная ошибка может произойти, если какой-либо файл с атрибутом "только-чтение" имеет то же самое имя, что файл соответствий компановщика. D2019 "Невозможно перезаписать исходный файл 'name'". Вы задали исходный файл в качестве выводного. Компилятор не позволяет исходному файлу быть перезаписанным одним из выход- ных файлов компилятора. D2020 "Опция -Gc требует возможности разрешения расширенных ключевых слов (-Ze)". Опция /Gc и опция /Za были заданы на одной командной строке. Опция /Gc требует возможности задания расширенного ключевого слова cdecl, если осуществляется доступ к библиотечным функ- циям. D2021 "Неверный числовой аргумент 'string'". Нечисловая строка была задана за опцией, требующей числового аргумента. D2022 "Невозможно открыть файл помощи cl.hlp". Была задана опция /HELP, но файл содержащий вспомогательные сообщения не был найден в текущем каталоге, либо в каталогах, заданных с помощью переменной PATH. 

    D.2.3. Предупреждающие сообщения командной строки.

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

    Номер Предупреждающие сообщения D4000 "Неизвестное предупреждение командной строки, свяжитесь с тех- нической службой фирмы Microsoft". Компилятором была обнаружена неизвестная ситуация. Пожалуйста, сообщите условия возникновения данной ситуации фир- ме Microsoft Corporation, используя бланк "Product Assistance Request", находящийся в конце данного руководства. D4002 "Неизвестная опция 'string' игнорируется". Одна из опций, заданных на командной строке, была нераспоз- нана и потому проигнорирована. D4003 "Для генерации кода выбран 80186/286, а не 8086". Были заданы обе опции: /G0 и /G2; преимущество дано опции /G2. D4004 "Оптимизация по времени, а не по размеру". Данное сообщение подтвердило использование для оптимизации оп- ции /Ot. D4005 "Невозможно выполнить 'filename'; пожалуйста, вставьте дискету и нажмите любой ключ". Команда QCL не может найти заданный выполняемый файл по задан- ному маршруту. D4006 "Разрешена только одна из опций -P/-E/-EP, выбрана -P". Было задано более одной выводной опции препроцессора. D4007 "Опция -C игнорируется (нужно задать также -P или -E, либо -EP)". Опция /C должна использоваться вместе с одной из выводных опций препроцессора (/E, /EP, /P). D4009 "Порог только для данных far/huge, игнорируется". Опция /Gt была использована в модели памяти, имеющей ближние указатели на данные. Она может применяться только для ком- пактной и большой моделей. D4010 "Опция -Gp не применяется, игнорируется". Версия операционной системы DOS Microsoft C не поддерживает профайлинг. D4013 "Комбинированный листинг имеет преимущество над объектным листингом" Если опция /Fc задана вместе с одной из опций /Fl или /Fa, соз- дается комбинированный листинг (/Fc). D4014 "Неверное значение number для строки 'string'. Используете ста- ндартное значение number". В контексте, требующем определенное числовое значение, было за- дано некорректное значение. D4017 "Конфликтующие опции проверки стэка-проверка стека отменяется". Вы задали на командной строке CL обе опции /Ge и /Gs. Опция Gs имеет преимущество, поэтому в данной программе стэковый конт- роль отменяется. 

    D.3. Сообщения об ошибках периода выполнения.

    Ошибки периода выполнения подразделяются на четыре категории: 1.Исключительные ситуации при выполнении операций с плавающей точкой математическим сопроцессором 8087/80287 или эмулятором. Данные ситуации описаны в Разделе D.3.1.

    2. Сообщения об ошибках, сгенерированные библиотекой периода выполнения, информирующие вас о серьезных ошибках. Данные сообщения перечислены и описаны в Разделе D.3.2.

    3. Сообщения об ошибках, сгенерированные во время обращения к процедурам обработки ошибок библиотеки периода выполнения — abort, assert, perror-как только программа вызовет процедуру. Данная процедура направляет сообщения в стандартный вывод. Описание данных процедур и соответствующих сообщений об ошибках смотрите в документе: «Справочное руководство по библиотеке процедур Microsoft-C».

    4. Сообщения об ошибках, сгенерированные вызовами математических процедур из библиотеки СИ периода выполнения. В случае ошибки математические процедуры возвращают ошибочное значение, а некоторые выводят сообщение на стандартной вывод. Описание математических процедур и соответствующие сообщения об ошибках смотрите в документе «Справочное руководство по библиотеке проц Microsoft-C».

    D.3.1. Исключительные ситуации операций с плавающей точкой.

    Сообщения об ошибках, перечисленные ниже, генерируются математическим сопроцессором 8087/80287. Описание сбоев оборудования смотрите в документации по процессорам семейства Intel. Данные ошибки могут быть также выявлены эмулятором операций с плавающей точкой, встроенным в стандартную библиотеку Quick-C.

    С помощью назначений управляющего слова сопроцессора 8087/80287, следующие исключительные ситуации маскируются и потому не происходят Исключительная Стандартное маскирующее действие

    ситуация

    Слишком малое число Ситуация маскируется Потеря значимости Результат приводится к нулю Потеря точности Ситуация маскируется 

    Информацию о том, как изменить управляющее слово операций с плавающей точкой, смотрите в справочных страницах, посвященных _control87, в документе «Справочное руководство по библиотеке процедур Microsoft C».

    Кроме того, следующие ошибки не возникают в коде, сгенерированном с помощью компилятора Microsoft Quick-C или полученном посредством стандартной СИ-библиотеки:

     Квадратный корень Выход за нижнюю границу стэка Неэмулируется 

    Исключительные ситуации при операциях с плавающей точкой имеют следующий формат:

     run-time error M61nn: MATH - floating-point error: messagetext 

    Номер Исключительные ситуации при операциях с плавающей точкой

    М6101 "Неверно". Произошла некорректная операция. Обычно это происходит при дей- ствиях с с неопределенностями. Данная ошибка приводит к останову программы с кодом завершения 129. Номер Исключительные ситуации при операциях с плавающей точкой М6102 "Слишком малое число". Было сгенерировано слишком малое число с плавающей точкой, даль нейшее его использование приведет к потере значимости. Такие ситуации обычно маскируются, они отлавливаются и обрабатывают- ся. Программа заканчивается с кодом завершения 130. М6103 "Деление на нуль". Была сделана попытка деления на нуль. Программа заканчивается с кодом 131. М6104 "Переполнение". При выполнении операции с плавающей точкой произошло переполне- ние. Программа заканчивается с кодом 132. М6105 "Потеря значимости". Во времы операции с плавающей точкой произошла потеря значимос- ти. Такие ситуации обычно маскируются; слишком малое значение заменяется нулем. Программа заканчивается с кодом завершения 133. М6106 "Потеря точности". Во время операции с плавающей точкой произошла потеря точности. Данная ситуация обычно проходит незамеченной, поскольку почти все операции с плавающей точкой могут привести к потере точнос- ти. Программа заканчивается с кодом 134. М6107 "Невозможна эмуляция" Была сделана попытка выполнить инструкцию сопроцессора 8087/ /80287, являющуюся некорректной и не поддерживаемую эмулятором. Программа завершается с кодом 135. М6108 "Квадратный корень". Операнд операции извлечения квадратного корня отрицателен. Про- грамма завершается с кодом 136. (обратите внимание, функция sqrt из библиотеки процедур языка СИ проверяет аргумент перед выполнением и возвращает ошибку, если аргумент отрицателен; описание функции sqrt смотрите в документе: "Справочное руко- водствопо библиотеке процедур Microsoft-C": М6110 "Переполнение стэка". Выражение с плавающей точкой привело к переполнению стэка на сопроцессоре 8087/80287 или эмуляторе. (ситуации переполнения стэка отлавливаются до предела 7 уровней в дополнение к восьми уровням, обычно поддерживаемым сопроцессором 8087/80287). Прог- рамма завершается с кодом 138. М6111 "Выход за нижнюю границу стэка". Выполнение операции с плавающей точкой на сопроцессоре 8087/80287 или эмуляторе вызвало выход за нижнюю границу стэка. Программа завершается с кодом 139. М6112 "Явно сгенерирована ошибка". Сигнал, означающий ошибку при выполнении операции с плавающей точкой, был послан с помощью вызова raise (SIGFPE). Программа завершается с кодом 140. 

    D.3.1. Сообщения об ошибках периода выполнения.

    Следующие сообщения описывают ошибки, сгенерированные в процессе выполнения программы. Номера ошибок периода выполнения лежит в пределах от R6000 до R6999.

    Сообщения об ошибках периода выполнения имеют следующую основную форму:

     run-time error R6nnn - messagetext (ошибка периода выполнения R6nnn) (- текст сообщения) 

    Номер Сообщение об ошибке периода выполнения

    R6000 "Переполнение стэка". Ваша программа переполнила пространство, отведенное под стэк. Это может произойти, если ваша программа использует большое количество локальных данных или является рекурсивной. Программа завершается с кодом 255. Чтобы исправить данную ситуацию, перекомпилируйте программу с помощью команды QCL с опцией /F и перекомпануйте программу, ис- пользуя опцию компановщика /STACK для размещения большого стэка R6001 "Присваивание нулевого указателя". В процессе выполнения программы было изменено содержимое сег- мента NULL. Сегмент NULL-это специальное место, расположенное по младшим адресам памяти, которое обычно не используется. Ес- ли содержимое сегмента NULL изменилось в процессе выполнения программы, это означает, что программа была записана на эту об- ласть, обычно, из-за примененного по небрежности нулевого ука- зателя. Заметим, что ваша программа может содержать нулевые указатели, но данное сообщение не будет генерироваться; данное сообщение появляется только в случае обращения к области памяти с помощью нулевого указателя Данная ошибка не будет вызывать останов программы; за сообщени- ем об ошибке следует нормальное завершение программы. Ошибка возвращает ненулевой код завершения. Данное сообщение отражает возможность серьезных ошибок в программе. Хотя программа, в ко- торой возникла такая ошибка, может работать правильно, она ве- роятно дает ошибки в будущем, и может дать сбой при работе в другой операционной среде. R6002 "Библиотека процедур операций с плавающей точкой не загружена". Ваша программа требует библиотеку с плавающей точкой, но данная библиотека не загружена. Программа завершается по ошибке с ко- дом 255. Такая ошибка может произойти в следующих двух ситуа- циях: 1.Программа была скомпилирована или скомпанована с такой опци- ей, как /FPi87, требующей сопроцессор 8087 или 80287, но прог- рамма выполняется на машине, не имеющей такого. Для исправления ошибки либо перекомпилируйте программу с опцией /FPi, либо ус- тановите сопроцессор. (В разделе 9.3.5 данного руководства вы найдете более подробную информацию о данных опциях и билиоте- ках. 2.Строка формата для одной из процедур семейства printf или scanf содержит спецификацию для формата с плавающей точкой, в то время, как значений или переменных с плавающей точкой в про- грамме нет. Компилятор Quick-C делает попытку минимизировать размер программы посредством загрузки библиотеки поддержки пла- вающей точки только в случае крайней необходимости. Поскольку в форматных строках не обнаружено спецификаций плавающей точки, необходимые процедуры для работы с плавающей точкой не были за- гружены. Для исправления данной ошибки используйте какой-либо аргумент с плавающей точкой для соответствия заданной специфи- кации формата. Это приведет к тому, что библиотека поддержки плавающей точки будет загружена. R6003 "Целое, деленное на нуль". Была сделана попытка разделить целое число на нуль, что дало неопределенный результат. Программа завершается с кодом 255. R6004 "Требуется версия DOS 2.0 или выше". Компилятор Quick-C не может работать на версиях операционной системы DOS младше 2.0. R6005 "Не хватает памяти для exec". Ошибки с R6005 по R6007 происходят при сбое в процедурах, вызы- ваемых одной из библиотечных, когда операционная система DOS не может вернуть управление в родительский процесс. Данная ошибка показывает, что для загрузки вызываемой программы не хватает памяти. R6006 "Неверный формат для exec". Файл, выполняемый одной из функций exec, не имеет формата, тре- буемого для выполняемого файла. R6007 "Некорректная среда для exec". Во время вызова одной из функций exec, операционная система DOS обнаружила некорректность среды для детского процесса. R6008 "Не хватает памяти для аргументов". R6009 "Не хватает памяти для программной среды". Ошибки R6008 и R6009 могут произойти при старте программы, если для загрузки программы хватает памяти, но недостаточно места для вектора argv, либо вектора envp, либо для обоих. Чтобы избежать данной проблемы перепишите процедуры _setargv или _setenvp R6012 "Некорректное обращение к ближнему указателю". В программе был использован нулевой ближний указатель. Данная ошибка может произойти только при включенном контроле на указатели (то есть, если программа была скомпилирована с опцией Pointer Check в диалоговой рамке Compile, опцией /Zr на команд- ной строке, либо при действующей прагме pointer_check). R6015 "Неожидаемое прерывание". Программа не может выполняться, поскольку она содержит неожида- емые прерывания. Когда прерывания создаются в программе из программного списка, работающей в программной среде, Quick-C автоматически создает объектные файлы и передает компановщику. Объектные файлы, пере- данные компановщику, содержат прерывания , требуемые для про- граммной среды Quick-C. Однако, вы не сможете запускать програ- мму, полученную из данных объектных файлов, вне программной среды Quick-C. 

    D.3.3. Ограничения периода выполнения.

    В таблице D.2 приведены ограничения, накладываемые на программы в период выполнения. Если ваша программа нарушает одно из данных ограничений, система выдает соответствующее сообщение об ошибке.

     Таблица D.2. Программные ограничения периода выполнения. Элемент данных Описание Ограничения Файлы Максимальный размер файла 232-1 байт (4 гигабайта) Максимальное число одновременно от- 20 крытых файлов (потоков). Командная строка Максимальное количество символов 128 (включая имя программы). Таблица операци- Максимальный размер. 32К онной среды. 

    Примечание:

    Пять стандартных потоков открываются автоматически (stdin, stdout, stderr, stdaux, stdprn), оставляя еще 15 потоков для нужд программы.


    D.4. Сообщения об ошибках компановщика.

    Данный раздел описывает сообщения об ошибках, генерируемые компановщиком LINK (Оверлейный компановщик фирмы Microsoft). При возникновении фатальной ошибки компановщик прерывает выполнение. Сообщения о фатальных ошибках имеют следующий формат:

    место возникновения: fatal error L1xxx: текст сообщения Нефатальные ошибки выявляют проблемы в выполняемом файле. Компановщик LINK строит выполняемый файл. Нефатальные ошибки имеют следующий формат:

    место возникновения: error L2xxx: текст сообщения

    Предупреждения также обозначают возможные проблемы в выполняемом файле. Компановщик LINK строит выполняемый файл. Предупреждения имеют следующий формат:

    место возникновения: warning L4xxx: текст сообщения

    В данных сообщениях-место возникновения-это входной файл, в котором обнаружена ошибка, либо программа LINK, если входного файла нет. Если входной файл-это файл .OBJ или .LIB и известно имя модуля, имя модуля заключается в скобки, как показано в следующем примере:

    SLIBC.LIB( file) MAIN.OBJ(main.c) TEXT.OBJ 

    Ошибки компановщика могут возникнуть, как при неявном его вызове с помощью команды QCL, так и при явном вызове с помощью команды LINK. Они могут также произойти и при компиляции программы, имеющей программный список, либо когда вы создаете на диске выполняемый файл в среде Quick-C. Если ошибка компановщика возникает в программной среде Quick-C, Quick-C высвечивает сообщение:

    Error during link phase No .EXE file produced (Ошибка в процессе компановки Выполняемого файла не создается). 

    Для просмотра ошибок компановщика нажмите ENTER, либо отметьте «мышью» командную кнопку OK. Ошибки последнего прохода компановщика хранятся в файле с именем LINK.ERR. В следующем списке приведены ошибки, возникающие во время компановки объектных файлов с помощью Microsoft Overlay Linker, LINK.

    Номер Сообщение об ошибке компановщика L1001 "'option': имя опции неясно". После индикатора опции (/) не появилось уникального имени оп- ции. Например, команда Link /N main; сгенерирует ошибку, поскольку программа LINK не может опреде- лить, какая из опций, начинающихся на букву "N" имеется в виду. L1002 "'option': нераспознанное имя опции". За индикатором опции (/) появился нераспознанный символ, как в следующем примере: LINK /ABCDEF main; L1004 "'option': неверное числовое значение". Для одной из опций было задано некорректное числовое значение. Например, для опции, требующей числовое значение, задана сим- вольная строка. L1006 "'option': размер стэка превышает 65535 байтов". Размер, определенный для стэка, превышает 65535 байтов. l1007 "'option': номер прерывания превышает 255". В качестве значения опции /OVERLAYINTERRUPT задано число, более 255. l1008 "'option': слишком большое предельное число сегментов". Было установлено предельное число сегментов, большее 3072 ( с помощью опции /SEGMENTS). L1009 "'option': CPARMAXALLOC: некорректное значение". Число, определенное в опции /CPARMAXALLOC не лежит в пределах 1-65535. L1020 "Не заданы объектные модули". Для компановщика не заданы имена объектных файлов. L1021 "Файлы соответствий вкладывать невозможно". Один файл соответствий оказался внутри другого файла соответст- вий. L1022 "Файл соответствий слишком длинный". Строка в файле соответствий длиннее 127 символов. L1023 "Выполнение прекращено пользователем". Вы нажали CONTROL+C. L1024 "Вложение правых скобок". В командной строке содержимое оверлея было написано некоррекн- но. L1025 "Вложение левых скобок". В командной строке содержимое оверлея было написано некоррекн- но. L1026 "Несоответствие правых скобок". В командной строке в спецификации содержимого оверлея пропуще- на правая скобка. L1027 "Несоответствие левых скобок". В командной строке в спецификации содержимого оверлея пропуще- на левая скобка. L1043 "Таблица распределения памяти переполнена". В программе задано более 32768 длинных вызовов, длинных перехо- дов, либо других длинных указателей. Попытайтесь заменить длинные ссылки короткими, если возможно, и перестроить объектный модуль L1045 "Слишком много записей TYPDEF. Объектный модуль содержит более 255 записей TYPDEF. Данные за- писи описывают общие переменные. Такая ошибка может возникнуть только в программах, созданных компилятором Microsoft Quick-C или другими компиляторами, поддерживающими общие переменные. (TYPDEF-это термин операционной системы DOS. Он разъясняется в документе "Справочное руководство программиста по операционной системе MS-DOS фирмы Microsoft" или других справочных книг по DOS.) L1046 "Слишком много внешних имен в одном модуле". В объектном модуле определено более 1023 внешних имен. Разбейте модуль на меньшие части. L1047 "Слишком много имен групп, сегментов, классов в одном модуле". Программа содержит слишком много имен групп, сегментов, клас- сов. Сократите число групп, сегментов или классов и перестройте объектный файл. L1048 "Слишком много сегментов в одном модуле". Объектный модуль имеет более 255 сегментов. Расщепите модуль или объедините сегменты. L1049 "Слишком много сегментов". Программа имеет более, чем максимально разрешенное число сег- ментов. (опция /SEGMENTS определяет максимально разрешенное число; стандартно 128). Повторите компановку с опцией /SEGMENTS с соответствующим чис- лом сегментов. L1050 "Слишком много групп в одном модуле". Программа LINK обнаружила более 21 определения групп (GRPDEF) в одном модуле. Сократите число определений групп или расщепите модуль. (Опре- деления групп разъясняются в документе "Справочное руководство программиста по MS-DOS" и в других справочных книгах по DOS. L1051 "Слишком много групп". В программе определено более 20 групп, не считая DGROUP. Сократите количество групп. L1052 "Слишком много библиотек". Была сделана попытка скомпановать более 32 библиотек. Объедините библиотеки, либо используйте модули, требующие мень- шего количества библиотек. L1053 "Переполнение таблицы имен". Компановщик не имеет достаточно места для размещения таблицы имен программы (таких, как глобальные, внешние, имена сегмен- тов, групп, классов, файлов). Объедините модули или сегменты и перестройте объектные файлы. Исключите столько глобальных имен, сколько возможно. L1054 "Требуемое количество сегментов слишком велико". Компановщик не имеет достаточно памяти для размещения таблицы, описывающей количество требуемых сегментов (стандартное число 128 или значение, определенное в опции /SEGMENTS). Повторите компановку снова, используя опцию /SEGMENTS для задания меньше- го количества сегментов (например, 64, если ранее было исполь- зовано стандартное значение), либо освободите некоторое коли- чество памяти путем удаления резидентных программ или паралле- льных задач. L1056 "Слишком много оверлеев". В программе определно более 63 оверлеев. L1057 "Запись данных слишком велика". Запись LIDATA (в объектном модуле) содержит более 1024 байтов данных. Это ошибка транслятора. (LIDATA-это термин операционной системы DOS, его объяснение можно найти в документе "Справочное руководство программиста по MS-DOS фирмы Microsoft" или в дру- гих справочных книгах по DOS. Обратите внимание, какой транслятор (компилятор или ассемблер) построил некорректный объектный модуль и при каких обстоятель- ствах. Пожалуйста, сообщите о данной ошибке, используя форму Product Assistance Request, находящуюся в конце данного руко- водства. L1070 "'name': размер сегмента превышает 64К". Заданный сегмент содержит более 64К кода или данных. Повторите компиляцию и компановку в большой модели памяти. L1071 "Сегмент _TEXT больше 65520 байтов". Данная ошибка вероятнее всего может случиться только в СИ-прог- раммах малой модели памяти, однако она может произойти и, если любая программа с сегментом, названным _TEXT, компануется пос- редством команды LINK с опцией /DOSSEG. Программы на языке СИ малой модели памяти должны резервировать адреса кода 0 и 1; для целей выравнивания этот предел увеличивается до 16. L1072 "Общая область больше 65536 байтов". Программа имеет более 64 общих переменных. Данная ошибка не мо- жет возникнуть в объектных файлах, сгенерированных с помощью Макроассемблера MASM (Microsoft Macro Assembler). Она возникает только в программах, полученных с помощью компилятороа, поддер- живающих общие переменные. L1080 "Невозможно открыть файл-листинг". Диск или корневой каталог переполнены. Удалите или переместите файлы, чтобы освободить место. L1081 "Переполнение при записи выполняемого файла". Диск, на который записывается выполняемый файл .EXE, переполнен Освободите место на диске и повторите компановку. L1083 "Невозможно открыть выполняемый файл". Диск или корневой каталог переполнены. Удалите или переместите файлы, чтобы освободить место. L1084 "Невозможно создать временный файл". Диск или корневой каталог переполнены. Освободите место на диске и повторите компановку. L1085 "Невозможно открыть временный файл". Диск или корневой каталог переполнены. Удалите или переместите файлы, чтобы освободить место. L1086 "Не хватает временного файла". Заметьте обстоятельства возникновения данной ситуации и свяжи- тесь с фирмой Microsoft Corporation, воспользовавшись формой "Product Assitance Request", находящейся в конце данного руко- водства. L1087 "Неожиданный конец временного файла". Диск с временным выходным файлом компановщика удален. L1088 "Переполнение при записи файла-листинга". При записи на диск файла-листинга диск переполнился. Освободите место на диске и повторите компановку. L1089 "'filename': невозможно открыть файл соответствий". Программа LINK не может найти заданный файл соответствий. Обыч- но, это опечатка при задании имени файла. L1090 "Повторно открыть файл-листинг невозможно" По запросу оригинальный диск не был заменен. Повторите компа- новку. L1091 "Неожиданный конец файла в библиотеке". Диск, содержащий библиотеку, был вероятно, удален. Установите диск, содержащий библиотеку и повторите компановку. L1093 "'filename':объектный файл не найден". Компановщик не может найти заданного объектного файла. Задайте правильное имя объектного файла и повторите компановку. L1101 "Некорректный объектный модуль". Один из объектных модулей является некорректным. Если данная ошибка произошла после перекомпиляции, пожалуйста, свяжитесь с фирмой Microsoft Corporation, воспользовавшись формой "Product Assitance Request", приложенной в конце данного руководства. L1102 "Неожиданный конец файла". Для библиотеки был обнаружен некорректный формат. L1103 "Попытка обращения к данным, лежащим за границами сегмента". Заданная запись в объектном модуле продолжена за границы сег- мента. Это ошибка транслятора. Заметьте, какой транслятор (ком- пилятор или ассемблер) создал некорректный объектный модуль, и обстоятельства, в которых он был создан. Пожалуйста, сообщите о данной ситуации в фирму Microsoft Corporation, воспользовав- шись формой "Product Assistance Request", находящейся в конце данного руководства. L1104 "'filename': некорректная библиотека". Заданный файл не является корректным библиотечным файлом. Дан- ная ошибка прекращает работу программы LINK. L1113 "Неразрешенная COMDEF; системная ошибка". Заметьте обстоятельства возникновения данного сбоя и свяжитесь с фирмой Microsoft Corporation, воспользовавшись формой Product Assistance Request, находящейся в конце данного руководства. L1114 "Файл не подходит для /EXEPACK; повторите компановку без опции /EXEPACK". В компануемой программе размер упакованного загружаемого обра- за плюс заголовок больше, чем неупакованный загружаемый образ. Повторите компановку с помощью опции /EXEPACK. L2001 "Запись fixup без данных". Запись FIXUPP не имеет непосредственно предшествующей записи данных. Вероятно, это ошибка компилятора. (Подробности о FIXUPP смотрите в документе "Справочное руководство программис- та по MS-DOS фирмы Microsoft"). L2002 "Переполнение записи fixup при "ближнем" вызове 'number' frame seg 'segname' target seg 'segname' target offset 'number'" Данную ошибку могут вызвать следующие условия: -Программа компилируется в малой модели памяти с опцией /NT. -Группа больше 64К. -Программа содержит междусегментные короткие переходы или меж- дусегментные короткие вызовы. -Имя элемента данных в программе не соответствует процедуре из библиотеки процедур, подключенной к компановке. -Объявление EXTRN в исходном файле на яхыке ассемблер появилось в теле сегмента, как в следующем примере: code SEGMENT public 'CODE' EXTRN main:far start PROC far call main ret start ENDP code ENDS Предпочтительна следующая конструкция: EXTRN main:far code SEGMENT public 'CODE' start PROC far call main start ENDP code ENDS Перепишите исходный файл и перестройте объектный файл. (Подроб- ную информация о frame segment и target segment вы найдете в документе "Справочное руководство программиста по MS-DOS фирмы Microsoft".) L2003 "Дальний вызов на данные собственного сегмента". Дальние вызовы на данные собственного сегмента не разрешаются. L2005 "Тип fixup не поддерживается". Оказалось, что тип fixup не поддерживается компановщиком фирмы Microsoft. Вероятно, это ошибка компилятора. Обратите внимание на обстоятельства данной ошибки и сообщите их в фирму Microsoft Corporation, воспользовавшись формой "Product Assistance Request", находящейся в конце данного руководства. L2012 "'name': несоответствие размера элемента массива". "Дальний" общий массив был описан с двумя или более различны- ми размерами элементов массива (например, первый раз массив был описан, как массив символов, а второй раз, как массив дейст- вительных чисел). L2013 "Запись LIDATA слишком велика". Запись LIDATA в объектном модуле имеет размер более 512 байтов, максимально разрешенного размера. Это ошибка компилятора. По- жалуйста, сообщите об условиях возникновения данной ошибки в фирму Microsoft, воспользовавшись формой "Product Assistance Request" в конце данного руководства. L2024 "'name': имя уже определено". Одно из специальных оверлейных имен, требуемое для поддержки оверлеев, было определено в объектном файле. L2025 "'name': имя определено более одного раза". Удалите из объектного файла лишние определения имен. L2029 "Неразрешенные внешние ссылки". В одном или более модулей одно или более имен описаны, как внешние, но они не были определены, как публичные ни в одном из модулей или библиотек. После сообщения появляется список нераз- решенных внешних ссылок, как показано в следующем примере: EXIT in file(s): MAIN.OBJ (main.for) OPEN in file(s): MAIN.OBJ (main.for) Имя, которое идет перед 'in file(s)'-это неразрешенное внешнее имя. На следующей строке-список объектных модулей, имеющих ссы- лки на данное имя. Это сообщение и список записываются также в файл карты распределения памяти, если он существует. L2041 "Стэк плюс данные превышает 64К". Общий размер стэкового сегмента программы плюс DGROUP превышает 64К; в результате, программа загружается неверно. L2043 "Стартовый адрес__ aulstart не найден". Если вы строите библиотеку Quick с использованием опции /Q, компановщик требует имя __aulstart, определенное, как стар- товый адрес. L4003 "Неразрешенный вызов: смещение offset". Данная ошибка может быть вызвана компиляцией программы в малой модели памяти с опцией /NT. L4012 "Опция /HIGH отменяет /EXEPACK". Опции /HIGH и /EXEPACK не могут быть использованы одновременно. L4015 "Опция /CODEVIEW отменяет /DSALLOCATE". Опции /CODEVIEW и /DSALLOCATE не могут быть использованы одно- временно. L4016 "Опция /CODEVIEW отменяет /EXEPACK". Опции /CODEVIEW и /EXEPACK не могут быть использованы одно- временно. L4020 "'name': размер сегмента кода превышает 65500". Сегмент кода размером 65501-65536 байтов в длину может на про- цессоре Intel 80286 быть обработан некорректно. L4021 "Нет стэкового сегмента". Программа не имеет стэкового сегмента, определенного с типом STACK. Данное сообщение не возникнет при обработке модулей, скомпилированных с помощью компилятора Microsoft Quick-C, но не с помощью Макроассемблера. Обычно, каждая программа должна иметь стэковый сегмент с типом объединения STACK. Если у вас есть особые причины не определять стэк или определить его без типа объединения STACK, вы можете проигнорировать данное сообщение. Данное сообщение может быть получено и при компановке с помощью LINK версий 2.40 и младше, поскольку данные компановщики просматривают библиотеки только один раз. L4031 "'name': сегмент описан более, чем в одной группе". Сегмент был описан, как член двух различных групп. Исправьте исходный файл и перестройте объектные файлы. L4034 "Более 239 оверлейных сегментов; лишние помещены в корень". В оверлеях не может быть объявлено более 239 кодовых сегментов. Все сегменты свыше данного предела помещаются в корень. L4045 "Имя выходного файла 'name'". Компановщик высветил в запросе "Run file" стандартное выходное имя файла, но поскольку была использована опция /Q, имя выход- ного файла было изменено. L4050 "Слишком много глобальных имен". Для получения отсортированного списка глобальных имен в файле распределения памяти была использована опция /MAP, но задано для сортировки слишком много имен (более 2048 имен по умолча- нию). Повторите компановку с опцией /MAP:number. Компановщик выдает неотсортированный список глобальных имен. L4051 "'filename': невозможно найти библиотеку". Компановщик не может найти заданный файл. Введите новое имя, новую спецификацию маршрута, или и то, и другое. L4053 "VM.TMP: некорректное имя файла; игнорируется". Имя VM.TMP появилось, как объектное имя файла. Переименуйте файл и повторите компановку. L4054 "'filename': невозможно найти файл". Компановщик не может найти заданный файл. Введите новое имя файла, новую спецификацию маршрута, либо и то, и другое. 

    D.5.Сообщения об ошибках утилиты LIB.

    Сообщения об ошибках, сгенерированные администратором библиотек, программой LIB, имеет один из следующих форматов:

     {filename|LIB}: fatal error U1xxx: текст сообщения {filename|LIB}: error U2xxx: текст сообщения {filename|LIB}: warning U4xxx: текст сообщения 

    Сообщение начинается именем входного файла (filename), если он существует, либо именем утилиты. Если возможно, программа LIB распечатывает предупреждение и продолжает работу. В некоторых случаях ошибки неисправимы и утилита LIB прекращает работу. Утилита LIB может высветить следующие сообщения:

    Номер Сообщения об ошибках утилиты LIB U1150 "Размер страницы слишком мал". Размер страницы входной библиотеки слишком мал, что означает некорректный входной файл .LIB. U1151 "Синтаксическая ошибка: неверная спецификация файла". Командный оператор, такой как знак минус(-) был задан без соот- ветствующего имени модуля. U1152 "Синтаксическая ошибка: наименование опции опущено". Знак опции слэш (/) был задан без следующей за ним опции. U1153 "Синтаксическая ошибка: значение опции пропущено". Опция /PAGESIZE была задана без соответствующего значения. U1154 "Неизвестная опция". Была задана неизвествная опция. В данный момент программа LIB распознает только опции /PAGESIZE. U1155 "Синтаксическая ошибка: некорректный ввод". Данная команда не следует правильному синтаксису утилиты LIB, описанному в Главе 10, "Создание библиотек Quick и автономных библиотек". U1156 "Синтаксическая ошибка". Данная команда не следует правильному синтаксису утилиты LIB, описанному в Главе 10, "Создание библиотек Quick и автономных библиотек". U1157 "Пропущена запятая или символ перехода на новую строку". В командной строке ожидалась запятая или возврат каретки, кото- рые не появились. Это может означать нечаянно поставленную запятую, как в следующей строке: LIB math.lib, -mod1+mod2; Эта строка должна иметь следующий вид: LIB math.lib -mod1+mod2; U1158 "Пропущен возврат каретки". Либо ответ на запрос "Output library", либо последняя строка в файле соответствий, используемого для запуска программы LIB, не заканчивается возвратом каретки. U1161 "Невозможно переименовать старую библиотеку". Программа LIB не может переименовать старую библиотеку с рас- ширением .BAK, поскольку версия .BAK уже существует с защитой "только-чтение". Измените защиту старой версии .BAK. U1162 "Невозможно повторно открыть библиотеку". Старая библиотека не может быть повторно открыта после того, как она была переименована с расширением .BAK. U1163 "Ошибка при записи файла перекрестных ссылок". Диск или корневая директория переполнены. Удалите или переком- пилируйте файлы, чтобы освободить место. U1170 "Слишком много имен". В библиотечном файле появилось более 4609 имен. U1171 "Не хватает памяти". Программе LIB не хватает памяти для работы. Удалите параллель- ные и резидентные программы и повторите попытку, либо увеличьте память. U1172 "Не хватает виртуальной памяти". Заметьте обстоятельства данного сбоя и уведомите фирму Microsoft Corporation, воспользовавшись формой "Product Assistance Request", находящейся в конце данного руководства. U1173 "Системный сбой". Обратите внимание на обстоятельства данного сбоя и уведомите фирму Microsoft Corporation, воспользовавшись формой "Product Assistance Request", находящейся в конце данного руководства. U1174 "mark: не размещено". Заметьте обстоятельства данного сбоя и уведомите фирму Microsoft Corporation, воспользовавшись формой "Product Assistance Request", находящейся в конце данного руководства. U1175 "free: не размещено". Заметьте обстоятельства данного сбоя и известите фирму Microsoft Corporation, воспользовавшись формой "Product Assistance Request", находящейся в конце данного руководства. U1180 "Запись извлекаемого файла потерпела неудачу". Диск или корневой каталог переполнены. Удалите или перемес- тите файлы, чтобы освободить место. U1181 "Запись в библиотечный файл потерпела неудачу". Диск или корневой каталог переполнены. Удалите или перемес- тите файлы, чтобы освободить место. U1182 "'filename': невозможно создать извлекаемый файл". Диск или корневой каталог переполнены, либо заданный извлекае- мый файл уже существует с защитой "только-чтение". Освободите место на диске, либо измените вид защиты файла. U1183 "Невозможно открыть файл соответствий". Данный файл соответствий не найден. U1184 "Неожиданный конец файла при вводе команды". В ответе на запрос был обнаружен символ конца файла. U1185 "Невозможно создать новую библиотеку". Диск или корневой каталог переполнены, либо библиотечный файл уже существует с защитой "только-чтение". Освободите место на диске или измените атрибуты защиты библиотечного файла. U1186 "Ошибка при записи новой библиотеки". Диск или корневой каталог переполнены. Удалите или переместите файлы для освобождения места. U1187 "Невозможно открыть VM.TMP". Диск или корневой каталог переполнены. U1188 "Невозможно записать в VM". Отметьте обстоятельства возникновения данного сбоя и сообщите в фирму Microsoft Corporation, воспользовавшись бланком "Product Assistance Request", находящейся в конце данного руко- водства. U1189 "Невозможно прочесть из VM". Обратите внимание на обстоятельства возникновения данной ошибки и сообщите в фирму Microsoft Corporation, воспользовавшись бланком "Product Assistance Request", находящейся в конце данного руководства. U1190 "Прервано пользователем". Вы прервали работу программы LIB до завершения работы. U1200 "'name': некорректный заголовок библиотеки". Входной библиотечный файл имеет неправильный формат. Он либо не является библиотечным файлом, либо разрушен. U1203 "'name': некорректный объектный модуль по ближнему адресу". Модуль, заданный по имени 'name', является некорректным объект- ным модулем. U2152 "'filename': невозможно создать листинг". Диск или каталог переполнены, либо файл перекрестных ссылок уже существует с защитой "только-чтение". Освободите место на диске, либо измените атрибуты файла. U2155 "'modulename': модуль не найден в библиотеке; игнорируется". Заданный модуль не найден во входной библиотеке U2157 "'filename': невозможно получить доступ к файлу". Программа LIB не могла открыть заданный файл. U2158 "'libraryname': неверный заголовок библиотеки; файл игнориру- ется". Входная библиотека имеет некорректный формат. U2159 "'filename': неверный формат 'hexnumber'; файл игнорируется". Опознавательный байт слова 'hexnumber' данного файла не имеет одного из следующих распознаваемых типов: библиотека Microsoft, библиотека Intel, объектный файл Micro- soft, архив XENIX. U4150 "'modulname': переопределение модуля игнорируется". Модуль был определен для добавления в библиотеку, но модуль с тем де именем уже есть в библиотеке. Либо, модуль с одним и тем же именем помещен в библиотеку дважды. U4151 "'symbol (modulename): переопределение имени игнорируется". Заданное имя определено более, чем в одном модуле. U4153 "'number': размер страницы слишком мал; игнорируется". Значение, определенное в опции /PAGESIZE меньше 16. U4156 "'libraryname': спецификация выходной библиотеки игнорируется". В дополнение к новому библиотечному имена была задана выходная библиотека. Например, задав: LIB new.lib+one.obj, new.lst,new.lib где new.lib еще не существует-вы получите ошибку. 

    D.6. Сообщения об ошибках утилиты MAKE.

    Ошибки, высвечиваемые в процессе работы утилиты поддержки программ Microsoft (MAKE) имеют один из следующих форматов:

     {filename|MAKE}: fatal error U1xxx: текст сообщения {filename|MAKE}: warning U4xxx: текст сообщения 

    Сообщения начинаются с имени входного файла (filename), если он существует, либо с имени утилиты. Если возможно, утилита MAKE печатает предупреждение и продолжает работу. В некоторых случаях ошибки являются неисправимыми и утилита MAKE прекращает работу. Сообщения, генерируемые утилитой MAKE, перечислены в данном разделе.

    Номер Сообщения об ошибках утилиты MAKE U1001 "Макроопределение больше, чем number". Было определено макро, имеющее значение строки, длинее установ- ленного числа, разрешающего максимальную длину. Попытайтесь пе- реписать файл описанний утилиты MAKE и расщепить макро на два меньших. U1002 "Бесконечно рекурсивное макро". Был определен циклический вызов макрокоманд, как в следующем примере: A=$(B) B=$(C) C=$(A) U1003 "Выход за пределы памяти". Во время обработки файла описаний утилита MAKE вышла за пределы памяти. Попытайтесь сократить размер файла описаний утилиты MAKE путем его реорганизации или расщепления на меньшие. U1004 "Синтаксическая ошибка: пропущено имя макрокоманды". Файл описаний утилиты MAKE содержит макроопределение без левой части (то есть строки, начинающейся с =). U1005 "Синтаксическая ошибка: пропущено двоеточие". В строке, которая должна содержать выходной файл/входной файл, не хватает двоеточия, разделяющего выходной файл и входной файл. Утилита MAKE требует любую строку, за которой следует пустая строка, чтобы считать ее строкой выходного/входного фай- ла. U1006 "'targetname': макрорасширение больше числа 'number'". Макрорасширение плюс длина любой строки, с которой оно может быть объединено, длинее установленного числа. Попытайтесь пере- записать файл описаний утилиты MAKE, расшепив макро на два ме- ньших. U1007 "Много источников". Правило вывода были определено более одного раза. U1008 "'name': невозможно найти файл или каталог". Заданные файл или каталог не могут быть найдены. U1009 "'command': список аргументов слишком длинный". Командная строка в файле описаний утилиты MAKE длиннее 128 бай- тов, что максимально разрешено в DOS. Перепишите команды, чтобы сделать список аргументов короче. U1010 "'filename': отказ доступа". Файл, определенный, как 'filename'-имеет атрибут "только-чте- ние. U1011 "'filename': не хватает памяти". Для выполнения программы утилите MAKE не хватает памяти. U1012 "'filename': неизвестная ошибка". Заметьте обстоятельства возникновения данной ошибки и сообщите о них фирме Microsoft Corporation, воспользовавшись бланком "Product Assistance Request", данным в конце данного руко- водства. U1013"'command': ошибка errcode". Одна из программ или команд, вызванная в файле описаний утилиты MAKE, завершилась с ненулевым кодом завершения. U1015 "'file': целевой файл не существует". Обычно, это не означает ошибку. Данное сообщение предупреждает пользователя о том, что целевой файл не существует. Утилита MAKE выполняет любые команды, заданные в блоке описаний, поско- льку в большинстве случаев выходной файл создается последней командой файла описаний утилиты MAKE. U4000 "'filename': не существует". Обычно, это сообщение не свидетельствует об ошибке. Оно пре- дупреждает пользователя о том, что указанный файл не существует MAKE выполняет все команды, заданные в блоке, так как в боль- шистве случаев отсутствующий файл будет создан последующими командами файла MAKE. U4001 "Зависимый файл 'filename' не существует; целевой файл 'filena me' не строится". Утилита MAKE не может продолжать, поскольку требуемый входной файл не существует. Удостоверьтесь, что все имена файлов при- сутствуют и что все они корректно описываются в файле описаний утилиты MAKE. U4013 "'command': ошибка errcode (игнорируется)". Одна из программ или команд, вызванных в файле описаний утилиты MAKE, возвратила ненулевой код ошибки, в то время, как утилита MAKE работала с опцией /I. Ошибки игнорируются и утилита про- должает работу. U4014 "Синтаксис: make options [name-value...] file options=[/n] [/d][/i][/s][/x file] Утилита MAKE была неправильно вызвана. Стартуйте утилиту зано- во, воспользовавшись синтаксисом, представленным в сообщении: make опции[имя-значение...] file опции=[/n][/d][/i][/s] [/x file]. 

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

    Вот 3 жизненно важных части любого хорошего сообщения об ошибке:

    • Четкое текстовое сообщение
    • Правильное размещение
    • Хороший визуальный дизайн

    Четкое текстовое сообщение

    1. Сообщение об ошибке должно быть понятным

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

    1-2RdNRoDJmqfArWaViXal-g

    2. Сообщение об ошибке должно быть полезным

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

    Например, Microsoft описывает проблему, и прямо в сообщении об ошибке предоставляет вариант ее решения.

    1-9eTjcpNOWtE7pEWXpiPivA

    3. Сообщение об ошибке должно подходить под определенную ситуацию

    Очень часто, веб-сайты используют одно сообщение об ошибке для всех схожих состояний. Оставили пустым поле ввода электронного адреса — «Введите правильный электронный адрес», пропустили символ «@» — «Введите правильный электронный адрес». MailChimp решает эту проблему иначе — они используют 3 разных сообщения об ошибке для каждого состояния процесса подтверждения электронной почты. Сначала проверяется, заполнено ли поле ввода. Затем проверяется введены ли символы «@», и «.».

    1-cbmeYu8zkwhuw-I6fxn5gQ

    4. Сообщение об ошибке должно быть вежливым

    Не вините пользователей в том, что они что-то не так сделали, даже если это так. Будьте вежливы, дайте им почувствовать себя комфортно.

    1-4C2I4mLoV7A2Xclp5xXYmg

    5. Используйте юмор, если он уместен

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

    1-cVp9802WuM8W1pb4kSRH-A

    Правильное размещение

    Хорошее сообщение об ошибке — это такое сообщение, которое вы увидите. Размещайте его рядом с элементами интерфейса, с которыми ошибка непосредственно связана.

    1-90bO1c3llbghosgQTH0hwA

    Правильный визуальный дизайн

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

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

    1-Gny4mwee7oJL1vQsNgJhkg

    Заключение

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

    F-паттерн: как пользователи просматривают контент

    Предыдущая статья
    F-паттерн: как пользователи просматривают контент

    Метрики, за которыми должен следить любой SEO аналитик

    Следующая статья
    Метрики, за которыми должен следить любой SEO аналитик

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