{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet/Docs/pulls/comments/61350173","id":61350173,"diff_hunk":"@@ -1,8 +1,181 @@\n-.. include:: /../common/stub-topic.txt\n+Error Handling\n+==============\n+By `Steve Smith`_\n \n-|stub-icon| Error Handling\n-==========================\n+When errors occur in your ASP.NET app, you can handle them in a variety of ways, as described in this article.\n \n-.. include:: /../common/stub-notice.txt\n+.. contents:: Sections\n+\t:local:\n+\t:depth: 1\n+\t\n+`View sample files <https://github.com/aspnet/Docs/tree/master/aspnet/fundamentals/error-handling/sample>`_\n \n-.. _issue: https://github.com/aspnet/Docs/issues/124\n\\ No newline at end of file\n+Configuring an Error Handling Page\n+----------------------------------\n+\n+In ASP.NET, you configure the pipeline for each request in the ``Startup`` class's ``Configure()`` method (learn more about :doc:`configuration`). You can add a simple error page, meant only for use during development, very easily. All that's required is to add a dependency on ``Microsoft.AspNet.Diagnostics`` to the project and then add one line to ``Configure()`` in ``Startup.cs``:\n+\n+.. literalinclude:: error-handling/sample/src/ErrorHandlingSample/Startup.cs\n+\t:language: csharp\n+\t:lines: 21-29\n+\t:dedent: 8\n+\t:emphasize-lines: 6,8\n+\n+The above code, which is built from the ASP.NET Empty Visual Studio template, includes a check to ensure the environment is development before adding the call to ``UseDeveloperExceptionPage``. This is a good practice, since you typically do not want to share detailed exception information about your application publicly while it is in production. :doc:`Learn more about configuring environments <environments>`.\n+\n+The sample application includes a simple mechanism for creating an exception:\n+\n+.. literalinclude:: error-handling/sample/src/ErrorHandlingSample/Startup.cs\n+\t:language: csharp\n+\t:lines: 58-63\n+\t:dedent: 12\n+\t:emphasize-lines: 3-6\n+\n+If a request includes a non-empty querystring parameter for the variable ``throw`` (e.g. a path of ``/?throw=true``), an exception will be thrown. If the environment is set to ``Development``, the developer exception page is displayed:\n+\n+.. image:: error-handling/_static/developer-exception-page.png\n+\n+When not in development, it's a good idea to configure friendly pages for common HTTP status codes. You can use :ref:`status code pages <status-code-pages>` for this purpose.\n+\n+Using the Developer Exception Page\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+The developer exception page displays useful diagnostics information when an unhandled exception occurs within the web processing pipeline. The page includes several tabs with information about the exception that was triggered and the request that was made. The first tab includes a stack trace:\n+\n+.. image:: error-handling/_static/developer-exception-page.png\n+\n+The next tab shows the contents of the Querystring collection, if any:\n+\n+.. image:: error-handling/_static/developer-exception-page-query.png\n+\n+In this case, you can see the value of the ``throw`` parameter that was passed to this request. This request didn't have any cookies, but if it did, they would appear on the Cookies tab. You can see the headers that were passed in the last tab:\n+\n+.. image:: error-handling/_static/developer-exception-page-headers.png\n+\n+.. _status-code-pages:\n+\n+Configuring Status Code Pages\n+-----------------------------\n+\n+By default, your ASP.NET app will not provide a rich status code page for HTTP status codes such as 500 (error) or 404 (not found). You can configure the ``StatusCodePagesMiddleware`` adding this line to the ``Configure`` method:\n+\n+.. code-block:: c#\n+\n+\tapp.UseStatusCodePages();\n+\n+By default, this middleware adds very simple, text-only handlers for common status codes. For example, the following is the result of a 404 Not Found status code:\n+\n+.. image:: error-handling/_static/default-404-status-code.png\n+\n+The middleware supports several different extension methods. You can pass it a custom lamba expression:\n+\n+.. code-block:: c#\n+\n+\tapp.UseStatusCodePages(context => \n+\t\tcontext.HttpContext.Response.SendAsync(\"Handler, status code: \" +\n+\t\tcontext.HttpContext.Response.StatusCode, \"text/plain\"));\n+\n+Alternately, you can simply pass it a content type and a format string:\n+\n+.. code-block:: c#\n+\n+\tapp.UseStatusCodePages(\"text/plain\", \"Response, status code: {0}\");\n+\n+The middleware can handle redirects (with either relative or absolute URL paths), passing the status code as part of the URL:\n+\n+.. code-block:: c#\n+\n+\tapp.UseStatusCodePagesWithRedirects(\"~/errors/{0}\");\n+\n+In the above case, the client browser will see a ``302 / Found`` status and will redirect to the URL provided.\n+\n+Alternately, the middleware can re-execute the request from a new path format string:\n+\n+.. code-block:: c#\n+\n+\tapp.UseStatusCodePagesWithReExecute(\"/errors/{0}\");\n+\n+The ``UseStatusCodePagesWithReExecute`` method will still return the original status code to the browser, but will also execute the handler given at the path specified.\n+\n+If you need to disable status code pages for certain requests, you can do so using the following code:\n+\n+.. code-block:: c#\n+\n+\tvar statusCodePagesFeature = context.Features.Get<IStatusCodePagesFeature>();\n+\tif (statusCodePagesFeature != null)\n+\t{\n+\t\tstatusCodePagesFeature.Enabled = false;\n+\t}\n+\n+Limitations of Error Handling During Client-Server Interaction\n+--------------------------------------------------------------\n+\n+ASP.NET apps have certain limitations to their error handling capabilities because of the nature of disconnected HTTP requests and responses. Keep these in mind as you design your app's error handling behavior.\n+\n+#. Once the headers for a response have been sent, you cannot change the response's status code.\n+#. If the client disconnects mid-response, you cannot send them the rest of the content of that response.\n+#. There is always the possibility of an error occuring one layer below your error handling layer.\n+#. Don't forget, error handling pages can have errors, too. It's often a good idea for production error pages to consist of purely static content.\n+\n+Following the above recommendations will help ensure your app remains responsive and is able to gracefully handle errors that may occur.\n+\n+Server Error Handling\n+---------------------\n+\n+In addition to ASP.NET, the server hosting your app will perform some error handling. In the case of IIS, this is described `here <https://technet.microsoft.com/en-us/library/cc731570(v=ws.10).aspx>`. For Kestrel, its built-in error handling behavior may be found `here <https://github.com/aspnet/KestrelHttpServer/blob/dev/src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs#L565>`. Requests that are not handled by your app will be handled by the server, and any error that occurs will be handled by the server's error handling. Any custom error pages or error handling middleware or filters you have configured for your app will not affect this behavior.","path":"aspnet/fundamentals/error-handling.rst","position":131,"original_position":131,"commit_id":"99e92a6038b1e31d840ee51f71857c6e4807a72f","original_commit_id":"99e92a6038b1e31d840ee51f71857c6e4807a72f","user":{"login":"danroth27","id":1874516,"avatar_url":"https://avatars.githubusercontent.com/u/1874516?v=3","gravatar_id":"","url":"https://api.github.com/users/danroth27","html_url":"https://github.com/danroth27","followers_url":"https://api.github.com/users/danroth27/followers","following_url":"https://api.github.com/users/danroth27/following{/other_user}","gists_url":"https://api.github.com/users/danroth27/gists{/gist_id}","starred_url":"https://api.github.com/users/danroth27/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danroth27/subscriptions","organizations_url":"https://api.github.com/users/danroth27/orgs","repos_url":"https://api.github.com/users/danroth27/repos","events_url":"https://api.github.com/users/danroth27/events{/privacy}","received_events_url":"https://api.github.com/users/danroth27/received_events","type":"User","site_admin":false},"body":"> In addition to ASP.NET\r\n\r\nIn addition to the error handling logic in your application","created_at":"2016-04-27T22:49:39Z","updated_at":"2016-04-27T22:49:39Z","html_url":"https://github.com/aspnet/Docs/pull/1146#discussion_r61350173","pull_request_url":"https://api.github.com/repos/aspnet/Docs/pulls/1146","_links":{"self":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/comments/61350173"},"html":{"href":"https://github.com/aspnet/Docs/pull/1146#discussion_r61350173"},"pull_request":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/1146"}}},"pull_request":{"url":"https://api.github.com/repos/aspnet/Docs/pulls/1146","id":66032145,"html_url":"https://github.com/aspnet/Docs/pull/1146","diff_url":"https://github.com/aspnet/Docs/pull/1146.diff","patch_url":"https://github.com/aspnet/Docs/pull/1146.patch","issue_url":"https://api.github.com/repos/aspnet/Docs/issues/1146","number":1146,"state":"open","locked":false,"title":"Error Handling","user":{"login":"ardalis","id":782127,"avatar_url":"https://avatars.githubusercontent.com/u/782127?v=3","gravatar_id":"","url":"https://api.github.com/users/ardalis","html_url":"https://github.com/ardalis","followers_url":"https://api.github.com/users/ardalis/followers","following_url":"https://api.github.com/users/ardalis/following{/other_user}","gists_url":"https://api.github.com/users/ardalis/gists{/gist_id}","starred_url":"https://api.github.com/users/ardalis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ardalis/subscriptions","organizations_url":"https://api.github.com/users/ardalis/orgs","repos_url":"https://api.github.com/users/ardalis/repos","events_url":"https://api.github.com/users/ardalis/events{/privacy}","received_events_url":"https://api.github.com/users/ardalis/received_events","type":"User","site_admin":false},"body":"Fixes #124 \r\n@Rick-Anderson @danroth27 ","created_at":"2016-04-11T17:35:15Z","updated_at":"2016-04-27T22:49:39Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c978f7963bab256b29d05a504dc80d011026d2b5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/aspnet/Docs/pulls/1146/commits","review_comments_url":"https://api.github.com/repos/aspnet/Docs/pulls/1146/comments","review_comment_url":"https://api.github.com/repos/aspnet/Docs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aspnet/Docs/issues/1146/comments","statuses_url":"https://api.github.com/repos/aspnet/Docs/statuses/99e92a6038b1e31d840ee51f71857c6e4807a72f","head":{"label":"aspnet:ardalis/error-handling","ref":"ardalis/error-handling","sha":"99e92a6038b1e31d840ee51f71857c6e4807a72f","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":28239455,"name":"Docs","full_name":"aspnet/Docs","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Docs","description":"Documentation for ASP.NET 5","fork":false,"url":"https://api.github.com/repos/aspnet/Docs","forks_url":"https://api.github.com/repos/aspnet/Docs/forks","keys_url":"https://api.github.com/repos/aspnet/Docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Docs/teams","hooks_url":"https://api.github.com/repos/aspnet/Docs/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Docs/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Docs/events","assignees_url":"https://api.github.com/repos/aspnet/Docs/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Docs/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Docs/tags","blobs_url":"https://api.github.com/repos/aspnet/Docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Docs/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Docs/languages","stargazers_url":"https://api.github.com/repos/aspnet/Docs/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Docs/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Docs/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Docs/subscription","commits_url":"https://api.github.com/repos/aspnet/Docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Docs/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Docs/merges","archive_url":"https://api.github.com/repos/aspnet/Docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Docs/downloads","issues_url":"https://api.github.com/repos/aspnet/Docs/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Docs/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Docs/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Docs/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Docs/releases{/id}","deployments_url":"https://api.github.com/repos/aspnet/Docs/deployments","created_at":"2014-12-19T17:38:02Z","updated_at":"2016-04-27T05:42:43Z","pushed_at":"2016-04-27T22:27:47Z","git_url":"git://github.com/aspnet/Docs.git","ssh_url":"git@github.com:aspnet/Docs.git","clone_url":"https://github.com/aspnet/Docs.git","svn_url":"https://github.com/aspnet/Docs","homepage":null,"size":43589,"stargazers_count":461,"watchers_count":461,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":753,"mirror_url":null,"open_issues_count":158,"forks":753,"open_issues":158,"watchers":461,"default_branch":"master"}},"base":{"label":"aspnet:master","ref":"master","sha":"c54c174b3c68ab31abfd296f86c9085c8249b4d2","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":28239455,"name":"Docs","full_name":"aspnet/Docs","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Docs","description":"Documentation for ASP.NET 5","fork":false,"url":"https://api.github.com/repos/aspnet/Docs","forks_url":"https://api.github.com/repos/aspnet/Docs/forks","keys_url":"https://api.github.com/repos/aspnet/Docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Docs/teams","hooks_url":"https://api.github.com/repos/aspnet/Docs/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Docs/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Docs/events","assignees_url":"https://api.github.com/repos/aspnet/Docs/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Docs/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Docs/tags","blobs_url":"https://api.github.com/repos/aspnet/Docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Docs/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Docs/languages","stargazers_url":"https://api.github.com/repos/aspnet/Docs/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Docs/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Docs/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Docs/subscription","commits_url":"https://api.github.com/repos/aspnet/Docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Docs/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Docs/merges","archive_url":"https://api.github.com/repos/aspnet/Docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Docs/downloads","issues_url":"https://api.github.com/repos/aspnet/Docs/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Docs/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Docs/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Docs/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Docs/releases{/id}","deployments_url":"https://api.github.com/repos/aspnet/Docs/deployments","created_at":"2014-12-19T17:38:02Z","updated_at":"2016-04-27T05:42:43Z","pushed_at":"2016-04-27T22:27:47Z","git_url":"git://github.com/aspnet/Docs.git","ssh_url":"git@github.com:aspnet/Docs.git","clone_url":"https://github.com/aspnet/Docs.git","svn_url":"https://github.com/aspnet/Docs","homepage":null,"size":43589,"stargazers_count":461,"watchers_count":461,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":753,"mirror_url":null,"open_issues_count":158,"forks":753,"open_issues":158,"watchers":461,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/1146"},"html":{"href":"https://github.com/aspnet/Docs/pull/1146"},"issue":{"href":"https://api.github.com/repos/aspnet/Docs/issues/1146"},"comments":{"href":"https://api.github.com/repos/aspnet/Docs/issues/1146/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/1146/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aspnet/Docs/pulls/1146/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet/Docs/statuses/99e92a6038b1e31d840ee51f71857c6e4807a72f"}}}}