Validating Class Data - oop

In my app, I am creating a series of validation classes to check, for example, that a user entered Name property of the class (from a WinForm) doesn't exceed the size of the varchar() in the database.
Currently, the validation code will throw a custom Exception if the Name field is too large. (The custom exception, when caught by the UI, will show the custom exception message in a MessageBox as opposed to my generic error form for regular exceptions.) Validation classes are in the app's class library, and are scoped as Friend. The flow looks like this:
The DLL's Public Service Layer used by the WinForms --(calls)--> Friend Validation Layer
The DLL's Public Service Layer used by the WinForms --(calls)--> Friend Data Access Layer if validation succeeds.
Simplified example:
Public Shared Sub CreateCustomer(cust as Customer)
Validation.Customer.ValidateForCreate(cust) ' scoped as Friend
Dal.Customer.Create(cust) ' scoped as Friend
End Sub
Is it "smart" design to have the Validation Layer throw custom exceptions back to the UI when validation fails?
Is it better design to just return True/False from the Validation Layer along with a String message of what failed, and have the Service Layer handle throwing exceptions?
Is it better design to just return True/False from the Validation Layer, and have the Services Layer bubble up the True/False to the UI along with a String message of what failed?
I'm trying to keep an object oriented approach. My opinion is that throwing custom exceptions doesn't break OOP principles, but I'd like other opinions :)

AFAIK the exception mechanism is in fact at the core of OOP methodology, and is actually encouraged where it is built into the programming language. I'd say having your validation throw a custom exception is very much a good thing, especially if you have several custom exceptions (NameTooLongException, NameIncludesNonStandardCharactersException...) that are self-documenting and easily readable to future maintainers of the code.
Once your exception reaches your service layer, you can decide whether to catch and handle it (this depends on your business logic) or let it go all the way to the UI. If the exception carries a meaningful error message that is always appropriate, perhaps letting the UI present it to the user is not a bad idea. (Bare in mind though that you may want to internationalize your application at some point, in which case the message will need to be in the correct language.)
My opinion is that layer separation, while sometimes purely logical, has its reasons, and exceptions should not be thrown from the back-end to the front-end, but this is more of a guideline than a rule. Bottom line, do what needs to be done, don't overthink the design.
Hope this helps somehow...
Yuval =8-)

Related

When and how to use Result in Kotlin?

I love the idea of Result.
I love having encapsulated try/catch.
But I’m a little confused about how and when to use Result.
I currently use it like this:
My adapters and services return a Result. Failures and stacktraces are logged but do nothing else
runCatching{
.... // do something cool
}.onFailure {
logger.error("Something bad happened ", it)
}
My Resource classes fold and handle the Result
return service.method().fold(
onFailure = {
Response.serverError().entity("Oops").build()
},
onSuccess = {
Response.ok().entity(doSomethingWith(it)).build()
}
)
Is this really the correct way to use a Result? Or is there a more idiomatic way to code in Kotlin?
TL;DR: never in business code (prefer custom sealed classes), but you can consider Result if you build a framework that must relay all kinds of errors through a different way than the exception mechanism (e.g. kotlin coroutines).
First, there is actually a list of use cases for the motivation of the initial introduction of Result, if you find it interesting. Also in the same document:
The Result class is designed to capture generic failures of Kotlin functions for their latter processing and should be used in general-purpose API like futures, etc, that deal with invocation of Kotlin code blocks and must be able to represent both a successful and a failed result of execution. The Result class is not designed to represent domain-specific error conditions.
Also, here is a very nice article by the lead Kotlin designer about exceptions in Kotlin and more specifically when to use the type system instead of exceptions.
Most of what follows is my personal opinion. It's built from facts, but is still just an opinion, so take it with a grain of salt.
Do not use runCatching or catch Throwable in business code
Note that runCatching catches all sorts of Throwable, including JVM Errors like NoClassDefFoundError, ThreadDeath, OutOfMemoryError, or StackOverflowError. There is usually almost nothing you can do with such JVM errors (even reporting them might be impossible, for instance in case of OOME).
According to the Java documentation, the Error class "indicates serious problems that a reasonable application should not try to catch". There are some very special cases where you might want to try to recover from error, but that is quite exceptional (pun intended).
Catch-all mechanisms like this (even catch(Exception)) are usually not recommended unless you're implementing some kind of framework that needs to attempt to report errors in some way.
So, if we don't catch errors (and instead let them bubble up naturally), Result isn't part of the picture here.
Do not catch programming exceptions in business code
Apart from JVM errors, I believe exceptions due to programming errors shouldn't really be handled in a way that bloats the business code either. Using error(), check(), require() in the right places will make use of exceptions to detect bugs that cannot be caught by the compiler (IllegalStateException, IllegalArgumentException). It often doesn't make sense to catch these exceptions in business code, because they appear when the programmer made a mistake and the logic of the code is broken. You should instead fix the code's logic.
Sometimes it might still be useful to catch all exceptions (including these ones) around an area of code, and recover with a high level replacement for the whole failed operation (usually in framework code, but sometimes in business code too). This will probably be done with some try-catch(Exception), though, but Result will not be involved here because the point of such code would be to delimit with try-catch the high-level operation that can be replaced. Low-level code will not return Result because it doesn't know whether there are higher level operations that can be replaced with something in case of programming errors, or if it should just bubble up.
Modeling business errors
That leaves business errors for result-like types. By business errors, I mean things like missing entities, unknown values from external systems, bad user input, etc. However, I usually find better ways to model them than using kotlin.Result (it's not meant for this, as the design document stipulates). Modelling the absence of value is usually easy enough with a nullable type fun find(username: String): User?. Modelling a set of outcomes can be done with a custom sealed class that cover different cases, like a result type but with specific error subtypes (and more interesting business data about the error than just Throwable).
So in short, in the end, I never use kotlin.Result myself in business code (I could consider it for generic framework code that needs to report all errors).
My adapters and services return a Result. Failures and stacktraces are logged but do nothing else
A side note on that. As you can see, you're logging errors in the service itself, but it's unclear from the service consumer's perspective. The consumer receives a Result, so who's reponsible with dealing with the error here? If it's a recoverable error then it may or may not be appropriate to log it as an error, and maybe it's better as a warning or not at all. Maybe the consumer knows better the severity of the problem than the service. Also, the service makes no difference between JVM errors, programming errors (IAE, ISE, etc.), and business errors in the way it logs them.

Checking preconditions on parameters in public methods

I'm going to ask your Point of view about a design matter.
The question is basically the following: a public method of an object should always check preconditions in its input parameters or is it better to love responsibility to the caller and "trust the flow" ?
I'm not talking about obvious preconditions such as checking for null to avoid null reference exceptions, but I'm referring to business preconditions in method parameters. This typical happens in DDD Services that perform some kind of validation on input parameters and return an object containing a feedback about that validation.
As an example consider a class CheckPerson having a public method PerformCheck with a single parameter of type Person. Imagine there is a business rule saying that this check doesn't make sense for blonde persons.
In my opinion this check is important and method name should reflect this rule (something like PerformCheckForNonBlondePerson).
Should I add these checks, or should I trust the caller?
Yes you should!
You need to differentiate between input validation and preconditions. Business rules, as you describe them, can be applied in both.
Input validation happens at the system boundary. You expect input validation to fail in some cases. When that happens, you should indicate the error to the client with a useful description of the error.
Preconditions, on the other hand, are part of the contract of a method (or a whole component) somewhere within your system. You always want to be sure this contract is adhered to, because your implementation will probably behave incorrectly otherwise. Here, we use guards to enforce the preconditions. A guard should always pass. If it does not, it is always a programmer error (as opposed to a user error).
#theDmi thanks for sharing your point of view.
I totally agree with your position.
The context when I'm currently working is a team of three people, implementing a large application with a good deal of business logic and domain rules to be taken into account.
The main reason I don't agree with the "trust the flow and delegate responsibility to the caller" philosophy is that this force every developer which is going to make a call to a domain service to explicitly read the code of such a service and to have a good knowledge about the business requirement behind that code.
In my opinion, this is not realistic and furthermore this is an error-prone process.
Domain layer in large application is called by every piece of application logic we are going to write and leaving all the responsibility to the caller is simply too dangerous in my opinion. We don't currently use any kind of library to enforce preconditions check, but I know there are several options out there :)

OOP: Should valid data be handled in the class or the frontend?

Let's say I have a polygon class. Its only private data is an array of points. Should the class be written assuming the array has at least 3 points, and the GUI or input part of the program makes sure there are three points? Or should the member functions test the data validity and return an error message if needed?
There are some good points in the other answers. I'll try and state them here:
Ultimately, the model is responsible for knowing if it is in a valid state or not.
The UI needs to be aware if the model is in a valid state.
The UI can protect the model from invalid states AND provide good user feedback by validating the inputs.
There are some challenges:
If the model and UI both have validation code, the result is either duplicated code in the model/UI or a split between between the model and UI of the validation responsibilities.
UI validation gets messy because some data fields depend on others. Imagine an application that collects zip code and state (for US postal addresses). If you change the state, do you want the UI to immediately pop a dialogue box that says "Invalid zip code"? No. That would be annoying. The UI should give the user a chance to put the model into a valid state.
Throwing exceptions to catch validation errors is a heavy-handed way of doing things. Usually, you will want something less obtrusive.
Here is what I like to do for complex validation:
Allow the user the enter invalid values.
Create a class called ValidationError that includes a human-readable description of a single validation error.
Provide model methods like getValidationErrors() and isValid().
Before committing any changes to the model, have the UI call isValid() and getValidationErrors(). If there are any validation errors, make the UI display the errors to the user. Prevent the user from continuing until the errors are fixed.
The advantages of this approach are:
- More control of validation. You can decide when and what you want to validate.
- Centralizes validation logic in the model. The UI is only responsible for getting and displaying errors generated by the model.
- Less risk of other other code making invalid changes to a model if the model calls isValid() before calling save/commit methods.
-No exception handlers.
Consider creating a ValidationRule class. Each rule contains the code to valid something and generate an error message if it is invalid. The ValidationRule class has a method validate(aModel). This is especially easy to do if your programming language supports closures or first-class functions.
This results in each model class can have a dynamic collection of ValidationRule objects it consults when isValid() or getValiationErrors() is called. Alternatively, use a visitor pattern so that the models are are completely decoupled from the validation. This is what I do in my validation frameworks.
In a distributed application where the model is not on the client, it is often wise to do some basic validation before sending changes to the server. The round-trip time between client and server can be pretty long and you don't want to send obviously invalid requests to the server.
Lastly, the validity of one object sometimes depends on data in a different object! In these situations I let validation rules accept multiple objects, and use the controller object (or I create a context object) to manage the validation at a less granular level.
GUI validation is just meant for user hint.
Model should be responsible for its own integrity, as data may come from different sources rather than user [e.g. a background sync].
IMHO, a well-designed class will always protect its invariants. Therefore, the class must validate and always ensure it's in a valid state.
The UI can do it too or just rely on the class.
Take a look at Mark Seemann's blog post here.
If the class is expected to have at least 3 points you have to ensure it through the class interface. One way to achieve this (the only and best, actually) is receiving the polygon's points in the class constructor parameters and throw an exception if the points are less than 3 (remember that in a good OOP design, exceptions must not be seen as errors, but as a violation of implicit contracts).
Then, you just have to keep unmodified the values of those points. Think as if they where "final" in Java. Remember that whatever makes your object a certain polygon amongst every conceivable possible polygon is never expected to be modified. For instance, if you assigned the points in the constructor, then those points should be preserved all through the object's lifecycle both in quantity and values.
Always recall the most pure definition of object in OOP: an object is a computational representation of a real life entity. If your object represents polygon P, then it should never change in order to represent another polygon or any other real life entity. And you must never create an object "Polygon" if it actually doesn't represent a real world polygon. And that is achieved only through class constructors.
Following these design guides, you'll never need to add code to validate your object is a polygon inside the Polygon class, since it is a true polygon in the object paradigm.
So do the try {} catch {} when creating the polygon and let the constructor throw a NotPolygonException if needed.

is there a proper way to handle multiple errors/exceptions?

in OO programming, is there some conceptual pattern, ideas, about handling multiple errors?
for example, i have a method that performs some checks and should return an error message for each error found
['name is too short', 'name contains invalid unicode sequences', 'name is too long']
now, should i use an array of exceptions (not thrown exceptions)?
or something like this is better:
class MyExceptionList extends Exception{
public Void addException(Exception e){}
public Array getExceptions(){}
}
any theory behind this argument will be appreciated!
(this isn't a request about a specific programming language, but a pure theoretical one)
thank you in advance
Unfortunately, many languages and frameworks (including C++, Java, and .net) use an exception-handling mechanism which requires the type of an an exception object to simultaneously answer many questions, including:
What happened
What actions need to be taken beyond stack unwinding
At what point should the system be considered to be in a "known" state, at least with regard to the problems indicated by the exception.
Unfortunately, while the answers to those questions are somewhat related, they are in reality far from 100% correlated. Unfortunately, the assumption that the type of an exception will be sufficient to answer all of those questions makes it difficult to deal sensibly with many situations.
If you have control over all the exceptions that can be thrown, it may be helpful to use an exception-handling paradigm where the exception-handling object includes a virtual IsResolved property or method along with a ShouldCatchAs<T> property or method that returns a T if the exception needs to be handled as a T. Such a paradigm would be able to smoothly handle situations where an exception occurs while unwinding the stack from an earlier exception (the existing exception and new one would be wrapped into a composite exception object, whose ShouldCatchAs property would combine those of the original exceptions, and whose IsResolved property should only return true when both of the original exceptions' IsResolved properties do likewise).
I don't know any way to integrate such behavior into the existing frameworks unless one catches and wraps all exceptions that don't fit the paradigm, but perhaps future frameworks can facilitate such things.
From my years of experience, dealing with errors is best done via logging them at all levels, and return true/false from functions, indicating success/fail.
Logging is implementation dependant. It could be to a file, to memory, and you can log messages, unique numbers, whatever, as long as the log will enable you to pinpoint the exact place of the error.
I sometimes use exceptions, in cases where I perform many operations, each one depending on the success of its predecessor. This makes the code cleaner, with no ifs for error checking. Nevertheless, this is not the main thing to care about. The main thing is log the errors, and return success/fail. Success/fail is needed so that you can decide whether to continue the normal way or not (such as not doing the indended operation because the read size may overrun the memory).
Two more important notes:
1) You must construct a super easy API to report (log) your messages, otherwise you will find yourself postponing this crucial thing, eventually not doing it.
2) It's essential for the log or report to be easily viewed and inform you about the problems as they accure. Otherwise you might find yourself not using the error report mechansim at all.
This is a very important subject to me, and I believe it to be one of the most important issues in software engineering. You can read more about it on my website
You shouldn't be throwing Exceptions then.
An Exception is meant for an exceptional case. Errors found on a validation method isn't considered "Exceptional", it's rather obvious that validation errors would occur.
An exceptional situation is when your attempt to connect to a database failed, for example.
You should log all validation errors to an array, and then format it and display it as you like.
Exceptions are not intended for validation, they are intended to be created when something that is different from what was expected happens during the execution. This is why you can't create many exceptions at once, but exceptions can be caused because some other exception happened, this is why they can have a parent exception named case.

Where to throw an exception in layered architecture?

I've an application that offers its Business Layer through a Service Layer developed with WCF.
What I'm thinking about is: this service layer offers operational method like Create, Update and so on. These operation then reroute these calls to the Business Layer. The question is: suppose that one of these call doesn't accept a null input value (like: Create a null object), where is the best place to perform the check? My personal answer is in both the places (service and business) as I can guarantee the reuse of the Business Layer without using the Service Layer and viceversa.
Am I right?
Thanks
Marco
Your library code or the code that is
used by higher-layers in your
application must always only throw
exceptions and never worry about how
to deal with them.
This is important because you may use this library at many places for different purposes.
In your application presentation layer, if you're consuming a library code and you're aware about the possible exceptions then do catch them with try/catch.
if you dont handle the error in the DAL or BLL, then it bubbles up until you catch it.
Exceptions do not get "overwritten".
If you handled it in the DAL then you no longer have an exception.
If you didnt fully handle it, then the BLL could still throw another exception because of an improperly handled error in the DAL.
The general rule goes like this:
Handle Specific errors and dont use a generic catch-all. Allow any unanticipated exceptions to bubble further up the stack.
Try running FxCop on your project to see where you are violating best practices.
http://www.gotdotnet.com/team/fxcop