Logging logic and data errors in MVC3 with Elmah - entity-framework

I have a Service layer in my MVC3 app, which plays the role of a Repository among other things, as a layer between my Data layer and the actual web application. I have coded all my GetById methods to be robust, using FirstOrDefault and not just First, because the Id is passed in a URL and cannot be guaranteed to be a valid Id.
I now find myself where I'm doing a FirstOrDefault, then only proceeding if the result is not null. I would like to log the event when it is null, and then proceed to do nothing etc. Now, I am already using Elmah to log unhandled exceptions, and I have very little experience with exception handling etc. in MVC3, but it occurs to me that it might be better for me to use a simple First, with Elmah logging the exception if no entity is found.
How should I approach this scenario, where an invalid Id is quite definitely an logic exception, but not a low level CLR exception? This is not like when somebody is asked to enter an Id and no entity is found for their search term, which is a normal logic result.

Generating exceptions can be expensive. You're initial approach of validating user input is more robust. I would recommend using a logging framework such as NLog (http://nlog-project.org) to log the case were an invalid ID is passed in.
If you would like to keep all of your log messages in Elmah, then you can decide to write directly to Elmah's error log instead of bubbling-up an exception.

Related

RESTful response for data corruption in a single entity when getting multiple entities

I'm currently facing a dilemma in choosing the most appropriate response for a REST API that GET multiple entities, when one of the entities has a data corruption error. Say I have a REST API like the following:
GET /employees?department=&manager=
that returns a list of employees, perhaps with some filtering applied.
When getting the data from upstream (a DB, or another web service, etc.), I discover that the data for one of the employees that match the condition is corrupted. For example, the data cannot be parsed or does not meet some precondition that is necessary for that data entity.
What would be the most appropriate (from an API point of view) RESTful response to this? Should I continue processing all the other employees and simply ignore the error and omit it in the response, or error out with 500 Internal Server Error, or include the error in the response in a separate field while returning the other "good" employees?
I know this is somewhat opinion-based, but some advice would be greatly appreciated.
If you want to return an error, this (to me) is a server-error and I think that 500 is indeed the most appropriate error.
Whether you want to return an error, or an incomplete list with warnings depends on what your application requires it to do.

Onion Architecture - What should an Interface do if has some Data to check after giving structured data (p.ex : an Object) to a Usecase

I have a REST API based on Onion Architecture.
But I have some challenges to apply this way of building a server. Concretely with what should be the behaviour of an Interface if has some data to check before giving structured data to a Usecase.
That is one of my problems:
I have some methods in the Interface that catch info about timers from the request. But I'm facing always the same question. Must I catch all and give to the Usecase and do all checks there, or instead of that, first I have to check if a timer exists in the DB (if i'm updating a timer) and after that do what I need?
This type of checks like Role of who is requesting and what is allowed to do or not, if timers exist, if user exists, if an user already exists and you can't create someone with the same username (I want an unique username restriction) etc, are annoying me because depending on where I'm doing the check, following strictly the Onion Architecture or not, I'm executing more or less code that sometimes is unnecessary.
If I check some things in the Interface, I am avoiding executing code that would be unnecesary. But I'm not following this Architecture correctly, and viceversa.
Any thoughts?

Entity framework multiple contexts for logging

I've seen a fair few articles/posts that recommend not having more than one context per request when using EF.
Is it valid to have a second context for logging purposes such as 'user x did y', 'failed login from z' etc.
The rationale behind this is that I'd like these errors to be logged even if there is an error while using the "main" context, ie. foreign key issues etc.
Is there another way to do this or if I head down this road is there any things to try and avoid?
You can always have more context instances if your application logic really needs them and ability to persist log to database even with invalid data in the main context can be considered as such situation. You just need to ensure that your updates do not run in the same transaction (they must use different DB connection as well) - that should be a default behavior unless you use TransactionScope.

CQRS - When a command cannot resolve to a domain

I'm trying to wrap my head around CQRS. I'm drawing from the code example provided here. Please be gentle I'm very new to this pattern.
I'm looking at a logon scenario. I like this scenario because it's not really demonstrated in any examples i've read. In this case I do not know what the aggregate id of the user is or even if there is one as all I start with is a username and password.
In the fohjin example events are always fired from the domain (if needed) and the command handler calls some method on the domain. However if a user logon is invalid I have no domain to call anything on. Also most, if not all of the base Command/Event classes defined in the fohjin project pass around an aggregate id.
In the case of the event LogonFailure I may want to update a LogonAudit report.
So my question is: how to handle commands that do not resolve to a particular aggregate? How would that flow?
public void Execute(UserLogonCommand command)
{
var user = null;//user looked up by username somehow, should i query the report database to resolve the username to an id?
if (user == null || user.Password != command.Password)
;//What to do here? I want to raise an event somehow that doesn't target a specific user
else
user.LogonSuccessful();
}
You should take into account that it most cases CQRS and DDD is suitable just for some parts of the system. It is very uncommon to model entire system with CQRS concepts - it fits best to the parts with complex business domain and I wouldn't call logging user in a particularly complex business scenario. In fact, in most cases it's not business-related at all. The actual business domain starts when user is already identified.
Another thing to remember is that due to eventual consistency it is extremely beneficial to check as much as we can using only query-side, without event creating any commands/events.
Assuming however, that the information about successful / failed user log-ins is meaningful I'd model your scenario with following steps
User provides name and password
Name/password is validated against some kind of query database
When provided credentials are valid RegisterValidUserCommand(userId) is executed which results in proper event
If provided credentials are not valid
RegisterInvalidCredentialsCommand(providedUserName) is executed which results in proper event
The point is that checking user credentials is not necessarily part of business domain.
That said, there is another related concept, in which not every command or event needs to be business - related, thus it is possible to handle events that don't need aggregates to be loaded.
For example you want to change data that is informational-only and in no way affects business concepts of your system, like information about person's sex (once again, assuming that it has no business meaning).
In that case when you handle SetPersonSexCommand there's actually no need to load aggregate as that information doesn't even have to be located on entities, instead you create PersonSexSetEvent, register it, and publish so the query side could project it to the screen/raport.

How do I pretend duplicate values in my read database with CQRS

Say that I have a User table in my ReadDatabase (use SQL Server). In a regulare read/write database I can put like a index on the table to make sure that 2 users aren't addedd to the table with the same emailadress.
So if I try to add a user with a emailadress that already exist in my table for a diffrent user, the sql server will throw an exception back.
In Cqrs I can't do that since if I decouple the write to my readdatabas from the domain model, by puting it on an asyncronus queue I wont get the exception thrown back to me, and I will return "OK" to the UI and the user will think that he is added to the database, when infact he will never be added to the read database.
I can do a search in the read database checking if there is a user already in my database with the emailadress, and if there is one, then thru an exception back to the UI. But if they press the save button the same time, I will do 2 checks to the database and see that there isn't any user in the database with the emailadress, I send back that it's okay. Put it on my queue and later it will fail (by hitting the unique identifier).
Am I suppose to load all users from my EventSource (it's a SQL Server) and then do the check on that collection, to see if I have a User that already has this emailadress. That sounds a bit crazy too me...
How have you people solved it?
The way I can see is to not using an asyncronized queue, but use a syncronized one but that will affect perfomance really bad, specially when you have many "read storages" to write to...
Need some help here...
Searching for CQRS Set Based Validation will give you solutions to this issue.
Greg Young posted about the business impact of embracing eventual consistency http://codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/
Jérémie Chassaing posted about discovering missing aggregate roots in the domain http://thinkbeforecoding.com/post/2009/10/28/Uniqueness-validation-in-CQRS-Architecture
Related stack overflow questions:
How to handle set based consistency validation in CQRS?
CQRS Validation & uniqueness