Некоторое время назад я писал об использовании оператора throw
. К сожалению, название этого поста несколько запутало проблему; я никогда не собирался предлагать, чтобы оператор throw
alert()
Я также не рекомендовал использовать его для сообщений конечным пользователям.
Дело в том, что когда вы пишете стороннюю библиотеку или API, то есть сценарий, предназначенный для разработчиков, а не для конечных пользователей, для программирования, оператор throw
как часть механизма проверки. Он может давать отзывы разработчиков непосредственно в консоли JavaScript, вместо того, чтобы постоянно выдавать предупреждения.
С момента написания этого поста я несколько раз использовал эту технику. Но проблема, которая продолжает появляться, состоит в том, как, когда вы вручную выдаваете ошибку, имя файла и номер строки, сообщенные с ошибкой, часто бесполезны.
Значения, которые вы получаете с объектом ошибки, указывают на файл и строку, в которую была выдана ошибка ; однако, если вы выдаваете ошибку вручную для проверки входных данных разработчика, вы действительно хотите сообщить им имя файла и номер строки их кода, где на самом деле находится их ошибка.
Итак, мы можем получить эту информацию?
Действительно, мы можем, по крайней мере, в Firefox. Браузеры Firefox и WebKit (Safari, Chrome и т. Д.) Предоставляют свойство stack
В нем перечислены все отдельные операторы, которые привели к ошибке: от того места, где она действительно произошла, до любых вызывающих операторов до самой высокой абстракции или события.
Мы можем проанализировать этот стек (одно строковое значение), чтобы получить детали, которые мы хотим; все, что находится внизу стека , обычно там, где находился вклад разработчика. Эта функция сделает свое дело:
function fail(message){ var inputerror = new Error(); inputerror.name = "nMyScript/ValidationError: "; inputerror.message = message; if(typeof inputerror.stack != "undefined") { var errorstack = inputerror.stack.split(/s*(@|at)s*/); errorstack = errorstack[errorstack.length - 1] .replace(/^s+|s+$/g, '') .split(/:([0-9]+)/); inputerror.fileName = errorstack[0]; inputerror.lineNumber = errorstack[1]; } return inputerror;}
Это будет тогда использоваться так:
throw(fail("Illegal value for foo"));
Я говорю, что то, что мы ищем, обычно находится внизу стека, потому что это представляет самый высокий уровень абстракции. Если сам вход разработчика не является высшим уровнем (например, если он абстрагирован в литерал функции), то нижняя часть трассы будет указывать на это.
По крайней мере, в Firefox!
Opera уже показывает трассировку стека в своем выводе ошибки, поэтому дополнительная информация, которую мы хотим, в любом случае есть. Но браузеры WebKit не показывают имя файла или номер строки в своих выходных данных, даже если они предоставляют необходимые свойства ошибок, и приведенный выше код работает.
Но все тестируют в Firefox, не так ли? Независимо от того, что используется для просмотра!
Миниатюра кредита: kagey_b
Если вы хотите узнать больше от Джеймса, подпишитесь на нашу еженедельную техническую новостную рассылку Tech Times .