Is this 4-tier architecture good?(Exception handling is important for me :) - n-tier-architecture

I have this layers in my application:
Entities
Database (with Entities reference)
Business (with database and Entities references)
User Interface (with Business and Entities references)
Here is an example of my codes:
UserDAL class in database layer:
public class UsersDal
{
databaseDataContext db;
public UsersDal()
{
try
{
db = new databaseDataContext(ConnectToDatabase.GetConnectionString());
}
catch (Exception ex)
{
throw ex;
}
}
public List<User> GetAllUsers()
{
try
{
return (from u in db.Users select u).ToList();
}
catch (Exception ex)
{
throw ex;
}
}
And so on...
In the UserBLL class in Business layer i write like this:
public class UsersBll
{
UsersDal user;
public UsersBll()
{
try
{
user = new UsersDal();
}
catch(Exception ex)
{
throw new ProjectException(Errors.CannotCreateObject, ex);
}
}
public List<User> GetAllUsers()
{
try
{
return user.GetAllUsers();
}
catch(Exception ex)
{
throw new ProjectException(Errors.CannotReadData, ex);
}
}
And in UI i write:
private void GetUsers()
{
try
{
UsersBll u = new UsersBll();
datagrid.DataSource = u.GetAllUsers();
}
catch(ProjectException ex)
{
MessageBox(ex.UserMessage);// and also can show ex.InnerException.Message for more info
}
}
Well, I use a ProjectException named class to produce an error contain a BLL created message by me and an Exception message that the OS automatically manipulate.
Also i create an enum of possible errors and a dictionary
here is some details about it:
namespace Entities
{
public enum Errors
{
CannotCreateObject,
CannotReadData,
CannotAdd,
CannotEdit,
CannotDelete,...
}
[global::System.Serializable]
public class ProjectException : Exception
{
public ProjectException(Errors er, Exception ex)
: base(errors[er], ex)
{
currentEx = er;//er is Errors enum
}
static ProjectException()
{
errors = new Dictionary<Errors, string>();
errors.Add(Errors.CannotCreateObject, "the application cannot connect to database!");
errors.Add(Errors.CannotReadData, "the application cannot read data from database"); //...
}
public string UserMessage
{
get
{
try
{
return errors[currentEx];
}
catch
{
return "Unknown error!";
}
}
}
Is this good?
it work for me fine.
what's your idea?

It is almost always wrong within a catch (ex) to do a throw ex;. Either just do throw; or else throw new whateverException("someMessage", ex);. The decision of whether to use the former form or the latter generally depends upon whether you are crossing an application layer. If an AcmeServerDatabaseWrapper, which derives from DatabaseWrapper type, is performing a query when an AcmeDatabaseTableNotFoundException is thrown, it should catch that and rethrow it as a DatabaseWrapperTableNotFoundException (if such a type exists) or as a DatabaseWrapperOperationFailedException. Client code which has an object derived from DatabaseWrapper should be able to know what types of exceptions that object will throw, without having to know what type of object it is. Any exception which escapes from the database layer without being wrapped is an exception the client code is unlikely to be able to handle sensibly, but might handle erroneously (thinking it occurred in a context other than where it actually happened).

Related

Is it possible to transform a future type?

Using a library that has a method like this one:
std::future<bool> action();
I find my self in a situation where I have to conform with project specific enum return types like:
enum Result { Ok, Failed, ConnectionDown, ServerError };
and the call site of action looks like this:
std::future<Result> act()
{
try {
return _actor->action(); // This returns a different type :(
// What to do here ??? ^
}
catch (ConnectionError const& e)
{
return std::make_ready_future<Result>(Result::ConnectionError);
}
catch (ServerError const& e)
{
return std::make_ready_future<Result>(Result::ServerError);
}
}
so essentially the library doesn't have specific return codes for error cases, they are rather emitted as exceptions. Handling that is easy because I can construct ready futures with the appropriate value. The problem (ironically) is with the non exceptional path, where the library's std::future<bool> has to be transformed to std::future<Result>.
It's pointless to .get() the result and construct a ready future based on its value (true -> Ok, false -> Failed) because this way I'm removing asynchronicity from my function. Is there a better way to handle this?
Waiting for continuation function (std::experimental::future::then)
, you probably want something like:
std::future<Result> act()
{
return std::async([&](){
try {
if (_actor->action().get()) {
return Result::Ok;
} else {
return Result::Failed;
}
}
catch (ConnectionError const& e) {
return Result::ConnectionError;
}
catch (ServerError const& e) {
return Result::ServerError;
}
});
}

Unable to check exception type in google test

I'm unable to check the exception throw by my code in gtests. Here's a snippet of the test suite which runs the test:
EXPECT_THROW({
try{
// Insert a tuple with more target columns than values
rows_changed = 0;
query = "INSERT INTO test8(num1, num3) VALUES(3);";
txn = txn_manager.BeginTransaction();
plan = TestingSQLUtil::GeneratePlanWithOptimizer(optimizer, query, txn);
EXPECT_EQ(plan->GetPlanNodeType(), PlanNodeType::INSERT);
txn_manager.CommitTransaction(txn);
TestingSQLUtil::ExecuteSQLQueryWithOptimizer(
optimizer, query, result, tuple_descriptor, rows_changed, error_message);
}
catch (CatalogException &ex){
EXPECT_STREQ("ERROR: INSERT has more target columns than expressions", ex.what());
}
}, CatalogException);
I'm pretty sure that CatalogException is thrown. I even tried getting the details of the thrown exception by outputting it to cerr, and it showed Exception Type: Catalog.
This is not a duplicate question, I searched for answers on SO and I'm not using new in my code which throws the error. Here's the snippet which does that:
if (columns->size() < tup_size)
throw CatalogException(
"ERROR: INSERT has more expressions than target columns");
Finally, here's the definition of CatalogException:
class CatalogException : public Exception {
CatalogException() = delete;
public:
CatalogException(std::string msg) : Exception(ExceptionType::CATALOG, msg) {}
};
The idea from EXPECT_THROW is, that the macro catches the exception. If you catch the exception by yourself, gmock don't now anything about a thrown exception.
I suggest to just write the statement into the EXPECT_THROW, which actually trigger the exception. Everything else can be written before.
For example:
TEST(testcase, testname)
{
//arrange everything:
//...
//act + assert:
EXPECT_THROW(TestingSQLUtil::ExecuteSQLQueryWithOptimizer( optimizer, query, result,
tuple_descriptor, rows_changed, error_message)
,CatalogException);
}
I assume, that TestingSQLUtil::ExecuteSQLQueryWithOptimizer is trigger the thrown exception.
addition:
I tried to rebuild your exception hierarchy. This example works for me very well. The test passes, which means the exception is thrown.
enum class ExceptionType
{
CATALOG
};
class Exception {
public:
Exception(ExceptionType type, std::string msg) {}
};
class CatalogException : public Exception {
CatalogException() = delete;
public:
CatalogException(std::string msg) : Exception(ExceptionType::CATALOG, msg) {}
};
void testThrow() {
throw CatalogException( "ERROR: INSERT has more expressions than target columns");
}
TEST(a,b) {
EXPECT_THROW( testThrow(), CatalogException);
}

Recommended Access Modifiers for Testability of Wrapper Methods

One thing I have started doing in my tests is to wrap error messages and string concatenations into methods or variables to keep my tests robust should the error message contents change later.
So for example, I would refactor something like this:
try{
someMethod();
}catch(e){
throw new Error('error message.');
}
into this:
let errorMessage = 'error message';
...
try{
someMethod();
}catch(e){
throw new Error(errorMessage);
}
Or something similar if the error message contains a variable or something.
My question is what would be the best way to do this in Typescript? In Java I would have them be package-protected, but here it seems Jasmine does not have access to methods like this if they are protected. I have also tried making them static.
Is there preferred method for this?
This is one occasion where you can transfer some good practices from other languages.
If you create custom exceptions, you can test their type, rather than the strings - and you can also ensure uniformity of error messages.
This example looks a bit convoluted, but it should give you an idea (adapted from page 163-168 Pro Typescript).
A base CustomException class is created that implements the Error interface and will sit beneath any custom error types we want in our application.
An InvalidDateException is created to represent a particular class of error, this is the only place the error message string needs to be stored in the application.
You can now look at particular kinds of error as in the example catch statement where instanceof is used to check the type.
All your custom exceptions are compatible with the Error interface, which required name and toString().
Code:
class CustomException implements Error {
protected name = 'CustomException';
constructor(public message: string) {
}
toString() {
return this.name + ': ' + this.message;
}
}
class InvalidDateException extends CustomException {
constructor(public date: Date) {
super('The date supplied was not valid: ' + date.toISOString());
this.name = 'InvalidDateException';
}
}
try {
throw new InvalidDateException(new Date());
} catch (ex) {
if (ex instanceof InvalidDateException) {
alert(ex.toString());
}
}

Test case for Struts2 2.3.24 using Strut2SpringTestCase (request object is coming as null)

I am trying to write unit test cases for my Struts2 action classes. My Test class extends SpringStrutsTestCase class. I am able to set the request object and able to get the action and action is also getting called but when in action it tries to get the parameters set in request object it throws null pointer exception i.e. request object is going as null. Below is my what my test class looks like. Any help is really appreciated.
import org.apache.struts2.StrutsSpringTestCase;
import org.junit.Test;
import com.opensymphony.xwork2.ActionProxy;
public class testClass extends StrutsSpringTestCase {
#Test
public void test1() throws Exception {
try {
request.setParameter("p1", "v1");
request.setParameter("p2", "v2");
ActionProxy proxy = getActionProxy("/actionName");
MyActionClass loginAction = (MyActionClass) proxy.getAction();
loginAction.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public String[] getContextLocations() {
String[] arr = new String[] { "one.xml", "two.xml", "three.xml" };
return arr;
}
}
Here is my action class.
public class MyAction extends ActionSupport{
private String p1;
private String p2;
/*
Gettere and Setters of p1 and p2
*/
public String execute() throws Exception {
// return "success";
logger.info("Login Action Called");
String pv1= (String) request.getParameter("p1");// If I get value using this.pv1 it works fine but with this code it doesn't.
String pv2= (String) request.getParameter("p2");
return "success";
}
}
In order to test an action call you need to call execute method of ActionProxy. By calling execute of your action you are just invoking that particular method of the action class and not S2 action along with the interceptors, results, etc.
The correct way would be:
ActionProxy proxy = getActionProxy("/actionName");
proxy.execute();
BTW if you're using JUnit 4 there is StrutsSpringJUnit4TestCase which you should use instead of StrutsSpringTestCase.

is this valid Factory pattern usage?

I made PageFactory class for Paging the list of data regardless which DBMS is used.
But I'm not sure that this is valid factory pattern or something's wrong.
If there's better way to to this could you tell me?
package com.tource.cms.common.database.paging;
import com.tource.cms.common.environment.EnvironmentVariables;
public class PageFactory {
private static final String DEFAULT_DATABASE_TYPE = getDefaultDatabaseType();
public static Page createPage(int totalRow, int currPage, int blockRow, int blockPage) {
if("mysql".equals(DEFAULT_DATABASE_TYPE))
return new MysqlPageCalculator(totalRow, currPage, blockRow, blockPage).getPage();
else if("oracle".equals(DEFAULT_DATABASE_TYPE))
return new OraclePageCalculator(totalRow, currPage, blockRow, blockPage).getPage();
else {
try {
throw new UnsupportedDatabaseException();
} catch (UnsupportedDatabaseException e) {
e.printStackTrace();
return null;
}
}
}
/** getting DBMS type from cached Memory */
private static String getDefaultDatabaseType() {
return EnvironmentVariables.get("cms.jdbc.databaseType").toLowerCase();
}
}
As long as MysqlPageCalculator and OraclePageCalculator implement the same interface, or the same super class, let's say PageCalculator, you are implementing Abstract Factory pattern correctly.
As you have extract the creation process of page into a standalone class instead key word 'new'. So yes, it is a Simple Factory pattern.