Skip to main content

Error messages while throwing exceptions

I was very concerned about exceptions, how they are thrown and handled. I define a proper error code before throwing some error. I never been to a production site, but this time I got a chance to be a implementation team. The way I handled my exceptions seems to be incomplete. Though, my error messages in exception was good, but it still missing a feature, which could help production people. Many of you might not aware of the very fact that, the logging level is severe in production. Then way you log the data in the codes is always helpful, but try to handle your error message for exceptions efficiently that you need not to enable logging to finer levels to analyze the issue. The errors must be self explanatory.

Analyze the code snippet mentioned below:

public void fetchCurrencyOffset(String bankCode, String branchCode, String currencyCode1, String currencyCode2) {
            try {
                  Map<String, Object> objectMap = new HashMap<String, Object>();
                  objectMap.put(CommonServicesConstants.CURRENCY_CODE_ONE, currencyCode1);
                  objectMap.put(CommonServicesConstants.CURRENCY_CODE_TWO, currencyCode2);
                  objectMap.put(CommonServicesConstants.BRANCH_CODE, branchCode);
                  objectMap.put(CommonServicesConstants.BANK_CODE, bankCode);
                  executeNamedQuery(CommonServicesQueryConstants.QUERY_TOGET_CCY_OFFSETFLAG, objectMap);
            } catch (BusinessException e) {
                  throw new BusinessException(CommonServicesErrorConstants.FAILED_LOAD_CURRENCY_PAIR);
            }
      }
      private void executeNamedQuery(String queryName, Map<String, Object> objectMap) {
            // Fire DataBase query.
      }  


It seems perfectly right, I don’t see any error in the above code snippet. Whenever, something breaks here in the above code snippet, it will surely, throw a relevant Business Exception. So, check the exception stack trace, how it looks like.

[2011-07-11T19:43:00.097+10:00] [host_server1] [ERROR] [] [com.test.practice.CurrencyService] [tid: [ACTIVE].ExecuteThread: '14' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: xxxxxx] [ecid: e9e4f880efb8a51d:-28bac7cc:1310f48109c:-8000-00000000000090af,0] [APP: xxxxxxx-middleware] XX_CS_CY_1015[[
com.test.practice.framework.exception.BusinessException: Failed to load Currency Pair
at com.test.practice.commonservice.currency.CurrencyService.fetchCurrencyOffset(CurrencyService.java:3891)
at com.test.practice.commonservice.currency.CurrencyService.fetchSpotRate(CurrencyService.java:1481)

Looking at the above stack trace, one can easily identify the error. So, I was in the dilemma that this is a good error message for exceptional handling practice. But I encountered this error in the production site also. When I was asked to look into the issue, I analyzed this issue and reported that Currency pair was missing from the database. When my supervisor asked me that which currency pair was missing?..I was like, I don’t have any answer, I asked him to enable the log level to fine level to check that. So, the problem was solved at that time. This is the point when I realized the importance of error messages of exception handling. Thus. I started looking for some alternative ways for the same. And, finally I discovered this, analyze the same code snippet now :

public void fetchCurrencyOffset(String bankCode, String branchCode, String currencyCode1, String currencyCode2) {
            try {
                  Map<String, Object> objectMap = new HashMap<String, Object>();
                  objectMap.put(CommonServicesConstants.CURRENCY_CODE_ONE, currencyCode1);
                  objectMap.put(CommonServicesConstants.CURRENCY_CODE_TWO, currencyCode2);
                  objectMap.put(CommonServicesConstants.BRANCH_CODE, branchCode);
                  objectMap.put(CommonServicesConstants.BANK_CODE, bankCode);
                  executeNamedQuery(CommonServicesQueryConstants.QUERY_TOGET_CCY_OFFSETFLAG, objectMap);
            } catch (BusinessException e) {
                  throw new BusinessException(CommonServicesErrorConstants.FAILED_LOAD_CURRENCY_PAIR, currencyCode1, currencyCode2);
            }
      }
      private void executeNamedQuery(String queryName, Map<String, Object> objectMap) {
            // Fire DataBase query.
      }


The above snippet also looks the same except the line where business exception is thrown.
Now, when the same error comes again, the stack trace looks a bit different.

[2011-07-11T19:43:00.097+10:00] [host_server1] [ERROR] [] [com.test.practice.CurrencyService] [tid: [ACTIVE].ExecuteThread: '14' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: xxxxxx] [ecid: e9e4f880efb8a51d:-28bac7cc:1310f48109c:-8000-00000000000090af,0] [APP: xxxxxxx-middleware] XX_CS_CY_1015[[
com.test.practice.framework.exception.BusinessException: Failed to load Currency Pair with ccy1 : INR and ccy2 : AUD
at com.test.practice.commonservice.currency.CurrencyService.fetchCurrencyOffset(CurrencyService.java:3891)
at com.test.practice.commonservice.currency.CurrencyService.fetchSpotRate(CurrencyService.java:1481)

Just a small change is required in the error message resource bundle and I was done.

So, after looking this stack trace, I can easily figure out the missing pair of currencies. Thus, for any error message, we always pass some piece of information in the error messages so, we need not to enable the fine level of the logging every time.

Comments

Popular posts from this blog

Listener refused the connection due to NetExcepti​on

I was testing some piece of code for calculation of new date on the basis of a given pattern and the specified date. I wrote a method to automate the test cases to generates those patterns and calculate the new date for each date of the specified date of the range of years. Since there were around 1 million pattern test cases are possible, so I want to insert this data in database for any future reference. After creating a pattern I was inserting data of the pattern and the calculation date along with the calculated date. It was working fine. I was prepare to hit the start button now, after testing different patterns individually. I hit the run button and it started its executions, but in the middle, I got this error. java.sql.SQLException: Listener refused the connection with the following error:ORA-12516, TNS:listener could not find available handler with matching protocol stack       at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:4...

Index Fast Full Scan

Index Fast Full Scan is one of the index access methods supported by Oracle. Index Fast Full Scan is otherwise called as Fast Full Index Scan also. Index Fast Full Scan can be imposed by Oracle Optimizer only in the certain scenario. The scenario where this index would be invoked is, Whenever the Oracle SQL optimizer detects that the query is serviceable without touching table rows, Oracle invokes this fast full index scan and quickly reads every block of the index without touching the table itself provided that query doesn’t contain any ORDER BY clause. The definition for this scan is more or less similar to the index full scan but the only difference is that former  will be invoked when ORDER BY clause is not mentioned in the query. It differs from the index full scan in another way where output won’t be in the sorted order since ORDER BY clause is not mentioned. If Oracle detects the query is serviceable without touching the table rows, it means, all the columns mentioned i...

Bitmap index

Bitmap index is one of the index types that is supported by oracle. Unlike B*tree index, this is very compressed index. It means if I create a bitmap index on a column, then the generated index table will be smaller when compared the index table which is generated by the binary index on the same column. The reason is, in bitmap index, ROWIDs won’t be stored in the index table, instead index values will be mapped against bitmaps. Bitmap is nothing but it stores either of this values, 1(Match) or 0(No Match). For each distinct values in the column, a separate index record will be created. Unlike b*tree index, bitmap index can accept NULL and it creates separate index entry for this. Bitmap index will work better if number of distinct values are relatively less when compared to the total number of records. Why is it referred as “relatively less”? this index will work fine if table of 1,000,000,000 records contains 5000 distinct values and if table of 1,000 records contains 5 distinct va...