{"action":"created","comment":{"url":"https://api.github.com/repos/nodules/terror/pulls/comments/27358326","id":27358326,"diff_hunk":"@@ -98,64 +131,70 @@ Terror.create = function(name, codes) {\n /**\n  * Extends existing CODE and MESSAGE hashes.\n  * @param {Object} codes { CODE_NAME: 'error message', … }\n- * @returns {Function} constructor\n- * @throws TerrorError if collisions detected.\n+ * @throws {Terror} TerrorError if collisions detected.\n+ * @returns {Terror} constructor\n  */\n-Terror.extendCodes = function(codes) {\n-    var ctor = this;\n-\n-    Object.keys(codes).forEach(function(code) {\n-        if (_has(ctor.CODES, code)) {\n-            throw new Error('Terror codes collision detected in the ' +\n-                ctor.prototype.name + '.extendCodes call for code \"' + code + '\"');\n+Terror.extendCodes = function (codes) {\n+    for (var code in codes) {","path":"lib/terror.js","position":157,"original_position":157,"commit_id":"e0d11305e6d9a7b571523b07c3196df626f953f5","original_commit_id":"e0d11305e6d9a7b571523b07c3196df626f953f5","user":{"login":"narqo","id":88045,"avatar_url":"https://avatars.githubusercontent.com/u/88045?v=3","gravatar_id":"","url":"https://api.github.com/users/narqo","html_url":"https://github.com/narqo","followers_url":"https://api.github.com/users/narqo/followers","following_url":"https://api.github.com/users/narqo/following{/other_user}","gists_url":"https://api.github.com/users/narqo/gists{/gist_id}","starred_url":"https://api.github.com/users/narqo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/narqo/subscriptions","organizations_url":"https://api.github.com/users/narqo/orgs","repos_url":"https://api.github.com/users/narqo/repos","events_url":"https://api.github.com/users/narqo/events{/privacy}","received_events_url":"https://api.github.com/users/narqo/received_events","type":"User","site_admin":false},"body":"[Есть мнения][1], что `for-in` — это очень не эффективно, в сравнении с \r\n\r\n~~~js\r\nvar codeNames=Object.keys(codes), code;\r\nfor(let i=0, len=codeNames.length; i<len; i++) {\r\n  code=codeNames[i];\r\n  ···\r\n}\r\n~~~\r\n\r\n[1]: https://github.com/iojs/io.js/pull/601#discussion_r23679732","created_at":"2015-03-29T20:14:16Z","updated_at":"2015-03-29T20:14:16Z","html_url":"https://github.com/nodules/terror/pull/25#discussion_r27358326","pull_request_url":"https://api.github.com/repos/nodules/terror/pulls/25","_links":{"self":{"href":"https://api.github.com/repos/nodules/terror/pulls/comments/27358326"},"html":{"href":"https://github.com/nodules/terror/pull/25#discussion_r27358326"},"pull_request":{"href":"https://api.github.com/repos/nodules/terror/pulls/25"}}},"pull_request":{"url":"https://api.github.com/repos/nodules/terror/pulls/25","id":32185345,"html_url":"https://github.com/nodules/terror/pull/25","diff_url":"https://github.com/nodules/terror/pull/25.diff","patch_url":"https://github.com/nodules/terror/pull/25.patch","issue_url":"https://api.github.com/repos/nodules/terror/issues/25","number":25,"state":"open","locked":false,"title":"Next level!","user":{"login":"B-Vladi","id":812310,"avatar_url":"https://avatars.githubusercontent.com/u/812310?v=3","gravatar_id":"","url":"https://api.github.com/users/B-Vladi","html_url":"https://github.com/B-Vladi","followers_url":"https://api.github.com/users/B-Vladi/followers","following_url":"https://api.github.com/users/B-Vladi/following{/other_user}","gists_url":"https://api.github.com/users/B-Vladi/gists{/gist_id}","starred_url":"https://api.github.com/users/B-Vladi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/B-Vladi/subscriptions","organizations_url":"https://api.github.com/users/B-Vladi/orgs","repos_url":"https://api.github.com/users/B-Vladi/repos","events_url":"https://api.github.com/users/B-Vladi/events{/privacy}","received_events_url":"https://api.github.com/users/B-Vladi/received_events","type":"User","site_admin":false},"body":"#### Предпосылки для изменений:\r\n* Хотелось реализовать поддержку стратегии обработки ошибок, при которой инстанс оборачивается на каждом логическом уровне приложения. Нехватало логирования стека всех экземпляров, а так же полного человекопонятного сообщения об ошибке. Про эту стратегию можно почитать [здесь] (http://habrahabr.ru/post/222761/).\r\n* В текущей реализации создание и логирование ошибок занимало заметное количество времени из-за формирования стека для каждого экземпляра, что совершенно ненужно. В нормальном боевом окружении разница в производительности может быть не заметна.\r\n\r\n#### Changelog:\r\n* `Terror` теперь может принимать вторым аргументом объект `error`.\r\n* Если вторым аргументом была передана строка, она не попадает в свойство `originalError`. Существуют сторонние обертки над ошибками, использующие значение из этого свойства. Если в нем содержится что-то отличное от `error`, возникало исключение при работе с `terror.originalError.stack`.\r\n* Свойство `Terror#message` содержит только оригинальное сообщение текущего объекта.\r\n* Новое свойство `Terror.stackTraceLimit` позволяет ограничивать глубину формируемого стека ошибки (если поддерживается интерпретатором). Может быть переопределено для любого конструктора, наследуемого от `Terror`. С помощью данного свойства можно сильно снизить нагрузку на процессор, если устанавить его значение в 0 на высоких уровнях приложения.\r\n* `Terror.isTerror` теперь не падает, если передать `null` или `undefined`.\r\n* `Terror#log` теперь логирует стеки всех обернутых ошибок.\r\n* Новый метод `Terror#getFullMessage` возвращает полное сообщение об ошибке, включая сообщения обернутых экземпляров. Сообщение каждого объекта ошибки воспринимается как предложение. Формат возвращаемого значения: `ERR_CODE Can not create page. Can not instance widget. a is no a function.`\r\n* Новый метод `Terror#getFullStack` возвращает стеки всех обернутых экземпляров. Каждый последующий стек отбивается четыремя пробелами слева (стандартный отступ стека). К каждому сообщению об ошибке добавляется код.\r\n* `Terror#setMessage` теперь не меняет сообщение в сформированном стеке.\r\n* Кастомные конструкторы теперь имеют полноценное имя (`MyError.name`).\r\n* Оптимизация производительности: `cd benchmark; npm test`.\r\n* Тесты переписаны на jasmine.\r\n* `Terror` теперь не зависит от NodeJS и может выполняться в любом окружении ([Issuse #1] (https://github.com/nodules/terror/issues/1)).\r\n* Мог что-то упустить.\r\n\r\n#### Что нужно сделать:\r\n* Портировать тесты на mocha, раз вы используете его. Удалить старые тесты.\r\n* Решить с форматом `Terror#getFullStack`, так как он сейчас жестко зашит в метод. Я бы оставил и так, ничего криминального в этом нет. `Terror#logMultilineError` тоже этим грешит.\r\n* Обновить `README.md` и JSDoc. Мой английский не позволяет это сделать грамотно.\r\n* Что-нибудь еще?","created_at":"2015-03-29T18:18:55Z","updated_at":"2015-03-29T20:14:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1e17fdf0ebd0371b57d332b4a2c071975fd01ecc","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nodules/terror/pulls/25/commits","review_comments_url":"https://api.github.com/repos/nodules/terror/pulls/25/comments","review_comment_url":"https://api.github.com/repos/nodules/terror/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nodules/terror/issues/25/comments","statuses_url":"https://api.github.com/repos/nodules/terror/statuses/e0d11305e6d9a7b571523b07c3196df626f953f5","head":{"label":"B-Vladi:master","ref":"master","sha":"e0d11305e6d9a7b571523b07c3196df626f953f5","user":{"login":"B-Vladi","id":812310,"avatar_url":"https://avatars.githubusercontent.com/u/812310?v=3","gravatar_id":"","url":"https://api.github.com/users/B-Vladi","html_url":"https://github.com/B-Vladi","followers_url":"https://api.github.com/users/B-Vladi/followers","following_url":"https://api.github.com/users/B-Vladi/following{/other_user}","gists_url":"https://api.github.com/users/B-Vladi/gists{/gist_id}","starred_url":"https://api.github.com/users/B-Vladi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/B-Vladi/subscriptions","organizations_url":"https://api.github.com/users/B-Vladi/orgs","repos_url":"https://api.github.com/users/B-Vladi/repos","events_url":"https://api.github.com/users/B-Vladi/events{/privacy}","received_events_url":"https://api.github.com/users/B-Vladi/received_events","type":"User","site_admin":false},"repo":{"id":31928236,"name":"terror","full_name":"B-Vladi/terror","owner":{"login":"B-Vladi","id":812310,"avatar_url":"https://avatars.githubusercontent.com/u/812310?v=3","gravatar_id":"","url":"https://api.github.com/users/B-Vladi","html_url":"https://github.com/B-Vladi","followers_url":"https://api.github.com/users/B-Vladi/followers","following_url":"https://api.github.com/users/B-Vladi/following{/other_user}","gists_url":"https://api.github.com/users/B-Vladi/gists{/gist_id}","starred_url":"https://api.github.com/users/B-Vladi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/B-Vladi/subscriptions","organizations_url":"https://api.github.com/users/B-Vladi/orgs","repos_url":"https://api.github.com/users/B-Vladi/repos","events_url":"https://api.github.com/users/B-Vladi/events{/privacy}","received_events_url":"https://api.github.com/users/B-Vladi/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/B-Vladi/terror","description":"Base error class which will help you organize errors, generate informative logs and as result grep logs more effectively","fork":true,"url":"https://api.github.com/repos/B-Vladi/terror","forks_url":"https://api.github.com/repos/B-Vladi/terror/forks","keys_url":"https://api.github.com/repos/B-Vladi/terror/keys{/key_id}","collaborators_url":"https://api.github.com/repos/B-Vladi/terror/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/B-Vladi/terror/teams","hooks_url":"https://api.github.com/repos/B-Vladi/terror/hooks","issue_events_url":"https://api.github.com/repos/B-Vladi/terror/issues/events{/number}","events_url":"https://api.github.com/repos/B-Vladi/terror/events","assignees_url":"https://api.github.com/repos/B-Vladi/terror/assignees{/user}","branches_url":"https://api.github.com/repos/B-Vladi/terror/branches{/branch}","tags_url":"https://api.github.com/repos/B-Vladi/terror/tags","blobs_url":"https://api.github.com/repos/B-Vladi/terror/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/B-Vladi/terror/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/B-Vladi/terror/git/refs{/sha}","trees_url":"https://api.github.com/repos/B-Vladi/terror/git/trees{/sha}","statuses_url":"https://api.github.com/repos/B-Vladi/terror/statuses/{sha}","languages_url":"https://api.github.com/repos/B-Vladi/terror/languages","stargazers_url":"https://api.github.com/repos/B-Vladi/terror/stargazers","contributors_url":"https://api.github.com/repos/B-Vladi/terror/contributors","subscribers_url":"https://api.github.com/repos/B-Vladi/terror/subscribers","subscription_url":"https://api.github.com/repos/B-Vladi/terror/subscription","commits_url":"https://api.github.com/repos/B-Vladi/terror/commits{/sha}","git_commits_url":"https://api.github.com/repos/B-Vladi/terror/git/commits{/sha}","comments_url":"https://api.github.com/repos/B-Vladi/terror/comments{/number}","issue_comment_url":"https://api.github.com/repos/B-Vladi/terror/issues/comments{/number}","contents_url":"https://api.github.com/repos/B-Vladi/terror/contents/{+path}","compare_url":"https://api.github.com/repos/B-Vladi/terror/compare/{base}...{head}","merges_url":"https://api.github.com/repos/B-Vladi/terror/merges","archive_url":"https://api.github.com/repos/B-Vladi/terror/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/B-Vladi/terror/downloads","issues_url":"https://api.github.com/repos/B-Vladi/terror/issues{/number}","pulls_url":"https://api.github.com/repos/B-Vladi/terror/pulls{/number}","milestones_url":"https://api.github.com/repos/B-Vladi/terror/milestones{/number}","notifications_url":"https://api.github.com/repos/B-Vladi/terror/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/B-Vladi/terror/labels{/name}","releases_url":"https://api.github.com/repos/B-Vladi/terror/releases{/id}","created_at":"2015-03-09T23:30:58Z","updated_at":"2015-03-29T16:57:53Z","pushed_at":"2015-03-29T16:57:53Z","git_url":"git://github.com/B-Vladi/terror.git","ssh_url":"git@github.com:B-Vladi/terror.git","clone_url":"https://github.com/B-Vladi/terror.git","svn_url":"https://github.com/B-Vladi/terror","homepage":"","size":191,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"nodules:master","ref":"master","sha":"d6dc0613d8a24af20f1da77c67d2a6e4e0481626","user":{"login":"nodules","id":4501174,"avatar_url":"https://avatars.githubusercontent.com/u/4501174?v=3","gravatar_id":"","url":"https://api.github.com/users/nodules","html_url":"https://github.com/nodules","followers_url":"https://api.github.com/users/nodules/followers","following_url":"https://api.github.com/users/nodules/following{/other_user}","gists_url":"https://api.github.com/users/nodules/gists{/gist_id}","starred_url":"https://api.github.com/users/nodules/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodules/subscriptions","organizations_url":"https://api.github.com/users/nodules/orgs","repos_url":"https://api.github.com/users/nodules/repos","events_url":"https://api.github.com/users/nodules/events{/privacy}","received_events_url":"https://api.github.com/users/nodules/received_events","type":"Organization","site_admin":false},"repo":{"id":10224470,"name":"terror","full_name":"nodules/terror","owner":{"login":"nodules","id":4501174,"avatar_url":"https://avatars.githubusercontent.com/u/4501174?v=3","gravatar_id":"","url":"https://api.github.com/users/nodules","html_url":"https://github.com/nodules","followers_url":"https://api.github.com/users/nodules/followers","following_url":"https://api.github.com/users/nodules/following{/other_user}","gists_url":"https://api.github.com/users/nodules/gists{/gist_id}","starred_url":"https://api.github.com/users/nodules/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodules/subscriptions","organizations_url":"https://api.github.com/users/nodules/orgs","repos_url":"https://api.github.com/users/nodules/repos","events_url":"https://api.github.com/users/nodules/events{/privacy}","received_events_url":"https://api.github.com/users/nodules/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nodules/terror","description":"Base error class which will help you organize errors, generate informative logs and as result grep logs more effectively","fork":false,"url":"https://api.github.com/repos/nodules/terror","forks_url":"https://api.github.com/repos/nodules/terror/forks","keys_url":"https://api.github.com/repos/nodules/terror/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nodules/terror/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nodules/terror/teams","hooks_url":"https://api.github.com/repos/nodules/terror/hooks","issue_events_url":"https://api.github.com/repos/nodules/terror/issues/events{/number}","events_url":"https://api.github.com/repos/nodules/terror/events","assignees_url":"https://api.github.com/repos/nodules/terror/assignees{/user}","branches_url":"https://api.github.com/repos/nodules/terror/branches{/branch}","tags_url":"https://api.github.com/repos/nodules/terror/tags","blobs_url":"https://api.github.com/repos/nodules/terror/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nodules/terror/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nodules/terror/git/refs{/sha}","trees_url":"https://api.github.com/repos/nodules/terror/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nodules/terror/statuses/{sha}","languages_url":"https://api.github.com/repos/nodules/terror/languages","stargazers_url":"https://api.github.com/repos/nodules/terror/stargazers","contributors_url":"https://api.github.com/repos/nodules/terror/contributors","subscribers_url":"https://api.github.com/repos/nodules/terror/subscribers","subscription_url":"https://api.github.com/repos/nodules/terror/subscription","commits_url":"https://api.github.com/repos/nodules/terror/commits{/sha}","git_commits_url":"https://api.github.com/repos/nodules/terror/git/commits{/sha}","comments_url":"https://api.github.com/repos/nodules/terror/comments{/number}","issue_comment_url":"https://api.github.com/repos/nodules/terror/issues/comments{/number}","contents_url":"https://api.github.com/repos/nodules/terror/contents/{+path}","compare_url":"https://api.github.com/repos/nodules/terror/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nodules/terror/merges","archive_url":"https://api.github.com/repos/nodules/terror/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nodules/terror/downloads","issues_url":"https://api.github.com/repos/nodules/terror/issues{/number}","pulls_url":"https://api.github.com/repos/nodules/terror/pulls{/number}","milestones_url":"https://api.github.com/repos/nodules/terror/milestones{/number}","notifications_url":"https://api.github.com/repos/nodules/terror/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nodules/terror/labels{/name}","releases_url":"https://api.github.com/repos/nodules/terror/releases{/id}","created_at":"2013-05-22T16:28:56Z","updated_at":"2015-03-10T10:01:03Z","pushed_at":"2015-03-29T18:18:57Z","git_url":"git://github.com/nodules/terror.git","ssh_url":"git@github.com:nodules/terror.git","clone_url":"https://github.com/nodules/terror.git","svn_url":"https://github.com/nodules/terror","homepage":"","size":464,"stargazers_count":22,"watchers_count":22,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":4,"forks":6,"open_issues":4,"watchers":22,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nodules/terror/pulls/25"},"html":{"href":"https://github.com/nodules/terror/pull/25"},"issue":{"href":"https://api.github.com/repos/nodules/terror/issues/25"},"comments":{"href":"https://api.github.com/repos/nodules/terror/issues/25/comments"},"review_comments":{"href":"https://api.github.com/repos/nodules/terror/pulls/25/comments"},"review_comment":{"href":"https://api.github.com/repos/nodules/terror/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nodules/terror/pulls/25/commits"},"statuses":{"href":"https://api.github.com/repos/nodules/terror/statuses/e0d11305e6d9a7b571523b07c3196df626f953f5"}}}}