{"id":335,"date":"2009-03-29T00:20:06","date_gmt":"2009-03-29T04:20:06","guid":{"rendered":"http:\/\/eligrey.com\/?p=335"},"modified":"2009-03-29T00:20:06","modified_gmt":"2009-03-29T04:20:06","slug":"custom-error-constructors","status":"publish","type":"post","link":"https:\/\/eligrey.com\/blog\/custom-error-constructors\/","title":{"rendered":"Custom error constructors"},"content":{"rendered":"<p>Most of the time, the <a href=\"https:\/\/developer.mozilla.org\/en\/Core_JavaScript_1.5_Reference\/Global_Objects\/Error#Error_types\">standard six native error constructors<\/a> and the one generic error constructor are not specific enough for an error. What if you want your library to throw a custom  <code>SecurityError<\/code> if it detects an XSS vector on a website? I made a function to create such constructors that behave the exact same way the native error constructors, like SyntaxError by using methods like <code>Error.prototype.toString<\/code> and the standard error object format. This code makes throwing a custom fake error constructor made with <code>ErrorConstructor(\"SyntaxError\")<\/code> have the same output as a native <code>SyntaxError<\/code> in a <a href=\"http:\/\/code.eligrey.com\/shell\/shell.html\">JavaScript shell<\/a>. I&#8217;ve tested the code in Firefox 3\/3.5 and Opera 9.6 and it seems to work fine. Comment and say if it works in your browser too.<\/p>\n<pre lang=\"javascript\">function ErrorConstructor(constructorName) {\n  var errorConstructor = function(message, fileName, lineNumber) {\n  \/\/ don't directly name this function, .name is used by Error.prototype.toString\n    if (this == window) return new arguments.callee(message, fileName, lineNumber);\n    this.name = errorConstructor.name;\n    this.message = message||\"\";\n    this.fileName = fileName||location.href;\n    if (!isNaN(+lineNumber)) this.lineNumber = +lineNumber;\n    else this.lineNumber = 1;\n  }\n  errorConstructor.name = constructorName||Error.prototype.name;\n  errorConstructor.prototype.toString = Error.prototype.toString;\n\n  return errorConstructor;\n}<\/pre>\n<p>Usage: <code>ErrorConstructor([constructorName])<\/code><br \/>\n<em>Note: If no constructorName is specified, the default of <code>Error.prototype.name<\/code> is used<\/em><br \/>\nUsage for generated error constructor: <code>errorConstructor([message[, location[, lineNumber]])<\/code><\/p>\n<p>Examples:<\/p>\n<pre lang=\"javascript\">var SecurityError = ErrorConstructor(\"Security Error\"),\nMarkupError = ErrorConstructor(\"(X)HTML Markup Error\");\n\/\/these will both throw a SecurityError starting with \"Security Error on line 83:\"\nvar xss_error = \"Possible XSS Vectorn\n\u00a0JSON XHR response parsed with eval()n\n\u00a0Recommended fix: Parse JSON with JSON.parse\";\nthrow new SecurityError(xss_error, \"\/js\/searchResultsJSONloader.js\", 83);\nthrow SecurityError(xss_error, \"\/js\/searchResultsJSONloader.js\", 83);\n\/\/these will both throw the following MarkupError:\n\/\/\"(X)HTML Markup Error on line 1: Invalid DOCTYPE\"\nthrow new MarkupError(\"Invalid DOCTYPE\");\nthrow MarkupError(\"Invalid DOCTYPE\");<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Most of the time, the standard six native error constructors and the one generic error constructor are not specific enough for an error. What if you want your library to throw a custom SecurityError if it detects an XSS vector on a website? I made a function to create such constructors that behave the exact [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[22,40,71,90,93],"class_list":["post-335","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-constructors","tag-errors","tag-hacks","tag-javascript","tag-javascript-snippets"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pfpUD-5p","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/posts\/335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/comments?post=335"}],"version-history":[{"count":0,"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/posts\/335\/revisions"}],"wp:attachment":[{"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/media?parent=335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/categories?post=335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eligrey.com\/blog\/wp-json\/wp\/v2\/tags?post=335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}