I created a Service Object (http://railscasts.com/episodes/398-service-objects), which basically creates two models, A and B, sets up the association between them where B belongs to A, and returns A (which in turn you can access B via A given the association).
On error, I return a hash with the error information. As I'm trying to test this method, I'm having an issue now where there are two possible types of returns: either a model (when it passes) or a hash with the error information.
Is this a signal that the design is wrong? I know when you test first (TDD) you avoid such design issues.
If it is an issue, then I know I would need to return an invalid A model. Assuming the model B throws an error on create, how would I still be able to return an invalid A model?
If returning an error hash is okay, how else can I design this method to be testing friendly?
Good insight and good question. :-) On the face of it, this seems like a good situation to raise a Ruby exception for the "error" case rather than returning as a hash as a result of the method call. You can define your own error class (probably should be a subclass of StandardError) and include the hash or whatever information you want as part of the error you raise. See http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html for a discussion of this general topic.
As for checking for the raising of errors in rspec, see the last answer to How to use RSpec's should_raise with any kind of exception?, including links to additional information.
If you want to present your API as a RESTful interface, the consensus seems to be to utilize the HTTP response codes to be to present exceptions, as discussed in How to handle REST Exceptions? If you do use the exceptional response codes (e.g. 40X) for presenting your exceptions, then the fact that you return a hash in that case and a model in the other case is not a bad smell, imho, as there is no expectation of consistency between the data that accompanies an error and the data that accompanies a successful return. In any event, I don't think returning an "invalid" model in the error case makes any sense, assuming you're not in fact creating/persisting the model in that situation.
You can test the type of result.
In rspec...
expect(actual).to be_an_instance_of(expected)
expect(actual).to be_a_kind_of(expected)
Related
We are using breeze.js with entity framework to initiate client side entity management.
We randomly get "Failed to set the ‘$visited’ property on ‘DOMStringMap’: ‘data-$visited’ is not a valid attribute name" error the the breeze.js from __toJSONSafe method of it.
does anybody have any idea what could make "obj._$visited" property undefined? It is coming up as undefined and that is causing the issue during call to the saveChanges()
I'm guessing ... it seems like you've added some kind of DOM object to the entity before saving it. I can't imagine how else you could be subjecting the DOMStringMap to __toJSONSafe.
Would need to know more precisely what object (and entity) is involved when you get this exception.
You say it happens randomly. That doesn't make it easy on any of us. If you can make it happen often enough to detect, you could patch the __toJSONSafe method in your local copy of breeze.debug.js so that you can better trap the error and the information about what makes it happen.
Come back and share that information with us.
I'm working on managed object validation. So far I'm done with property-level validation. Now I'm meditating above inter-property validation. I could do it by one big if-else control flow but wondering if there is more elegant option.
I've found NSValidationPredicateErrorKey with
For predicate-based validation, key for the predicate for the
condition that failed to validate.
in documentation.
Somehow I sense this could be my pick, but I've found nothing on this topic. I searched official documentation, SO, reputable blogs, Core Data book by Marcus S. Zarra.
So what is predicate-based validation? Does it even exist? Is it even relevant if not documented? What are the use cases? If inter-propery validation, what is the example?
Simply override validateForInsert and validateForUpdate in your managed object subclasses to implement inter-property validation, as shown in the documentation to be found here (with code example).
The "predicate-based" validation can be achieved via the rich managed object API. Each NSManagedObject has an associated NSEntityDescription (a property called entity). Via this you can get to the NSPropertyDescription of each property. Property descriptions in turn have a property called validationPredicates, an array of NSPredicates for validation. Please note that these are read-only and they are primarily used for informing the error objects in case of validation errors. Also, to my understanding, they cannot always describe adequately the validation happening in the overrides mentioned above.
In summary, this error key you found is not really an indication that there is a generic, predicate-based way of specifying validation constraints. Instead you will have to override the above methods in the managed object classes.
First of all, I have to say that I understand how Data Annotation -based Model Validation works in ASP.NET MVC4 and I have it successfully implemented with DataAnnotationsModelValidatorProvider. So I don't need assistance on setting it up.
But when it comes down to HtmlHelpers, I'm struggling with trying to figure the context of the error message. And by saying context, I mean which error we're talking about. Which Attribute returned the error?
What I can get, is the Key for the error and the current ErrorMessage but programmatically, there's nothing, that at least I'm aware of, that would communicate which error we're talking about. Whether it was Required attribute or some other attribute, there's not way that I can find how to distinguish them.
Let's open the scenario a little bit. I have custom HtmlHelpers to render ContentEditable elements. For example Html.ContentEditableValidationMessageFor(m => m.firstName);. It will output something like this:
<span contenteditable="true" data-valmsg-for="firstName" data-valmsg-replace="Please provide first name" class="field-validation-error">Please provide first name</span>
Now, I do have a jQuery plugin to handle and persist the changes in the contenteditable element and it will persist them into the backend. However, the UI has nothing that would say which error message we're talking about. Humans can easily see it's the RequiredAttribute, but programmatically there's no data to differentiate it from some MinLengthAttribute for example.
In this scenario, if I would simply use the data-valmsg-for="firstName" as the key for the localization, that'd return the same error message for all the errors concerning the same property.
To Round it Up
What would be the Best Practise, when ModelState is available, to emit a unique ID for ModelError? Considering I'm using ASP.NET MVC4 and DataAnnotationsModelValidatorProvider.
I can think of tons of ways to "Hack it Together" but I would like to use the ModelState and whatever MVC provides. If it all goes down to writing a custom ModelValidatorProvider, then I'm all open for it. As long as it is the best and most sustainable way of going about it. I'm all for Doing More Now and Less Later than Hacking it Now and Hacking it Forever to Keep It Working
Can you give some context around the need to know which rule triggered the validation error, could it be a case of you trying to do something you shouldn't have too?
In general I use FluentValidation (http://fluentvalidation.codeplex.com/wikipage?title=mvc) in place of Data Annotation validation for many reasons, de-cluttering models, unit testing validation logic, allowing vastly more complex validation that include business logic. If your free to use 3rd party libraries I'd give it a look as it has always solved any validation problems I've had in the past.
It lets you write c# code that deals with your model validation via a fluent API. It has an MVC extension that wires everything up for you so other than creating the models validation class there is little impact from then on. An example for your code snippet above would be...
RuleFor(modelname => modelname.FirstName).NotEmpty().WithMessage("lease provide first name");
Even implementing ModelValidatorProvider will not help, it is just a mechanism to provide ModelValidators based on Model Metadata. When during model binding process in a controller action ModelValidators are being invoked the result is just ModelValidationResult which only contains MemberName and a text Message.
I think there is a dirty way to find out which ModelValidator is failed by checking the error message like this:
var modelErrors = ModelState.Where(m => m.Value.Errors.Count > 0).Select(m => new { Name=m.Key , Errors=m.Value.Errors});
by checking ErrorMessage of Errors for each key in modelErrors against ValidatorProvider error messages you can find out the error belongs to which Validator.
The Optimistic ConcurrencyException is not returned right. I tested this with the breeze ToDo sample and my app.
This is what is returned if i provoke a an OptimisticConcurrencyException:
{"$id":"1","$type":"System.Web.Http.HttpError, System.Web.Http","Message":"An error has occurred."}
The ExceptionType is missing. In debug-mode in VS this works right.
#sascha - You beat me to it on the <customErrors> thing which works fine if you're running in IIS (see Jimmy Bogard's alternative if you are one of the very few who would self-host your Web Api).
But I’m pretty sure it is the wrong thing to do ultimately. It is expedient for now but, as Jimmy says in his post, “It’s likely not something we want in production.” An app shouldn’t expose unfiltered exceptions to the client for routine stuff like optimistic concurrency or validation errors.
I intend to find a better approach, most likely involving the HttpResponseException as described here. I'll give strong consideration to a “Custom Exception Filter” for dealing with unhandled exceptions in a controlled manner.
I don’t think that approach is something that belongs in Breeze itself. It strikes me as requiring an application specific solution … one that knows which exceptions should be exposed and how they should be phrased. But the mechanism would be good to teach. Once you know how to do it, you can roll your own custom exception handling ... and leave the Web.config alone.
Hoping to write this guidance soon. Feel free to beat me to it :)
Hm..., when I attempt a concurrency exception in my test cases.
// assuming this causes a concurrency exception
em.saveChanges().then(
).fail(function(error) {
// error object detailed below
})
I get the following returned with the 'error' parameter
error.message: "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."
error.responseText: {"$id":"1","$type":"System.Web.Http.HttpError, System.Web.Http","Message":"An error has occurred.","ExceptionMessage":"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.","ExceptionType":"System.Data.OptimisticConcurrencyException","StackTrace":" at System.Data.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 <... more here ...> }
error.detail: < an even more detailed error object
error.detail.ExceptionType: "System.Data.OptimisticConcurrencyException"
There are other properties but these are the important ones.
I wonder what we are doing differently?
I'm using the UpdateModel method for validation. How do I specify the text for the error messages as they appear in the validation summary?
Sorry, I wasn't entirely clear. When I call UpdateModel(), if there is parsing error, for example if a string value is specified for a double field, a "SomeProperty is invalid" error message is automatically added to the ModelState.
How do I specify the text for said automatically generated error message?
If I implement IDataErrorInfo as suggested, it's error message property gets called for every column, regardless of whether the default binder deems it valid or not.
I'd have to reimplement the parse error catching functionality that I get for free with the default binder.
Incidentally, the default "SomeProperty is invalid" error messages seem to have mysteriously dissappeared in the RC. A validation summary appears and the relevant fields are highlighted but the text is missing! Any idea why this is?
Thanks again and I hope all this waffle makes sense!
This tutorial is a good example of the IDataErrorInfo technique - it makes adding validation parameters easy by adding them as attributes directly to the properties of the model classes.
These examples also may help - slightly different approaches to validating.
Additionally, this creative idea (which also implements IDataErrorInfo) may be a help to you.
Implement IDataErrorInfo on your model.