title: Where to format exception message and how to report it to client
body: <p>In our ASP.NET MVC 5 DDD application, I can't decide where to format exception message and how to correctly report it to client. I care about separation of concerns, DRY and correct REST implementation. In this case, I'm concerned about 4XX exceptions (not logged).</p>
  
  <p>For example, client (via ajax POST) wants to move two items 'ABC' and 'DEF' to folder 'XYZ'. The request goes from controller through service to DAL and exception is thrown in DAL due to DB constrains (e.g., name 'DEF' already exists in target folder - and this exception must originate in DAL, service layer can't deal with concurrency). At the very end, I want to display html-formatted, localized message, such as "Can't move item <strong>DEF</strong> to <strong>XYZ</strong>, name <strong>DEF</strong> already exists." (or as JSON with appropriate data). As a reply, I'd like to return HTTP status code 409, so this message ends up in jQuery's ajax error function. I really don't want to return 200 OK and end up in ajax success function, since it goes against REST principles (this request didn't succeed).</p>
  
  <p>My problem (and question) consists of two parts:
  1) where to format the message,
  2) how to correctly relay this error message to ajax error function.</p>
  
  <p>I considered (1a) to create MoveItemsException class and set fully formatted message where the exception was thrown (= in DAL) - but I really feel that DAL shouldn't be responsible for HTML formatting of error message, and also that message property should contain only plain text only. This is related question, <a href="https://stackoverflow.com/questions/2553679/formattedexception-instead-of-throw-new-exceptionstring-format-in-net">FormattedException instead of throw new Exception(string.Format(...)) in .NET</a>, but it doesn't solve the question "where" to format the message.</p>
  
  <p>I also considered (1b) to create MoveItemsException class and add appropriate properties to the exception (e.g., DTO or ID of item(s) that caused this exception), keep exception message property empty and format appropriate text in controller based on exception's content. This seems better, but it's not DRY, I'd have to repeat this in each instance where I'd be dealing with this exception. Anyway, this article reasonably advocates this approach: <a href="https://stackoverflow.com/questions/7320080/should-you-report-the-message-text-of-exceptions">Should you report the message text of exceptions?</a></p>
  
  <p>And another option (1c) is to implement formatting to the exception class itself, something like exception.FormatMessage(), but unlike in (1b), FormatMessage() wouldn't have access to broader context.</p>
  
  <p>Then, once I have formatted message, I'd like to correctly deliver this error message to ajax error function. I can use (2a)</p>
  
  <pre><code>var message = ...
  
  return new HttpStatusCodeResult(HttpStatusCode.Conflict, message);
  </code></pre>
  
  <p>This was suggested e.g. here, <a href="https://stackoverflow.com/questions/8702103/how-to-report-error-to-ajax-without-throwing-exception-in-mvc-controller">How to report error to $.ajax without throwing exception in MVC controller?</a>, it would be simple (since I'd get message as errorThrown parameter), but I don't think that HTML-formatted message (or JSON) is actually status description, that much better place for formatted error message is in response text (2b), e.g.:</p>
  
  <pre><code>var message = ...
  
  Response.StatusCode = 409;
  Response.Write(message);
  
  return new EmptyResult();
  </code></pre>
  
  <p>or in this case, I'd create my own ActionResult with similar functionality.</p>
  
  <p>What do you think is the best approach for forementioned scenario?</p>
  
  <p>EDIT:</p>
  
  <p>For now, my solution is to catch specific 4XX exception (with payload) in controller, map the exception to viewmodel, set status code to corresponding status, e.g. <code>Response.StatusCode = 409;</code> and then return partial view for that specific exception <code>return PartialView("_MoveError", moveErrorViewModel);</code></p>