1

Good day everyone, I create a batch process class. The problem I have at the moment, is that how will I check if there is an error encountered during the batch iteration. In my case, I've tried to process a batch with 8 iterations. From 1 to 6 there is no error. But during the 7th iteration, an error occur saying Too many query rows: 50001. My question is how will I check if some problem occur in the batch ? So far what I've tried are the following.

  1. I put try and catch in my executable class and add variable to check if it enter the catch statement.but it seems it is not working.

2.I also try to put system.debug(); inside my finish class but it seems that when an error occured it will not read the finish method. I also try to add query in my finish which is something like this:

AsyncApexJob batchResult = [Select Id, Status, NumberOfErrors, JobItemsProcessed,  
    TotalJobItems, CreatedBy.Email, ExtendedStatus  
      from AsyncApexJob where Id = :bc.getJobId()];

But still it doesn't work.

What is the best way to fix my problem. Please help.

3
  • Can you put debug statement inside your batch method? as far as I know there should be logs displayed per single execution. Problem with try/catch is that id doesnt catch limit exceptions. You can add some limit statements into your queries, probably dynamically, to ensure that you would not hit it, and create some document with logs or insert some attachments. About dynamic limit calculation here in answers - salesforce.stackexchange.com/questions/10041/…
    – kurunve
    Commented Feb 29, 2016 at 9:29
  • @kurunve thank you. Yes I already tried that. But all debug statement under the error part will not be read. Actually the above scenario is just an example. What I want is how to check if any error occur during the process.
    – Hope
    Commented Feb 29, 2016 at 9:36
  • Then just use scenario that I send via link to avoid that limitation for querying records and in case of warning (like amount of returned records is equal to limit that left) do some notification
    – kurunve
    Commented Feb 29, 2016 at 9:39

1 Answer 1

2

The last paragraph of this Exception Statements documentation explains why your try/catch doesn't help in this case:

Exceptions that Can’t be Caught

Some special types of built-in exceptions can’t be caught. Those exceptions are associated with critical situations in the Force.com platform. These situations require the abortion of code execution and don’t allow for execution to resume through exception handling. One such exception is the limit exception (System.LimitException) that the runtime throws if a governor limit has been exceeded, such as when the maximum number of SOQL queries issued has been exceeded. Other examples are exceptions thrown when assertion statements fail (through System.assert methods) or license exceptions.

When exceptions are uncatchable, catch blocks, as well as finally blocks if any, aren’t executed.

So as it is not possible to handle governor limit exceptions you have to come up with a code design that avoids them.

The quick fix is to try reducing your batch size: keep halving it until the code works then halve it one or two more times to provide some headroom.

But the real fix may be to change the query structure so that the number of rows returned is predictable. For example, querying child objects of the object that the batch runs over results in an unpredictable number of rows; instead making the child object the object that the batch runs over can result in a predictable number of rows and so guarantee that the governor limit exception won't happen. But exactly what approach you need to take depends on the details of what you are trying to accomplish.

PS

An example of re-throwing (see comment thread):

try {
    ...
} catch (Exception e) {
    // Do whatever error reporting/processing you want here
    // Then re-throw so the error also appears in AsyncApexJob
    throw e;
}
7
  • thank you so much very clear explanation +rep. What I tried here is to make some fail safe functionality. I did not just focus on one possible error. Another example of error is "time limit exceeded". I want to trap any possible error that might happen. Is it not possible ?
    – Hope
    Commented Feb 29, 2016 at 9:47
  • @Hope You can catch many exceptions and so do your own error reporting but I suggest you still re-throw those exceptions so the right status is reported in AsyncApexJob. But as described in the answer, any governor limit problem can't be handled that way and it may be exactly those problems that you are wanting to handle...
    – Keith C
    Commented Feb 29, 2016 at 9:52
  • I didn't quite understand what you mean. But speaking of AsyncApexJob I've tried to query it inside my finish method as what i've said in my question. But, it seems when an error occur during the execute method the finish method will not be read. Can you please further explain what you mean ?
    – Hope
    Commented Feb 29, 2016 at 10:05
  • @Hope From what you describe, when a governor limit exception happens the finish method does not get called so you can't do anything from within the batchable which I know is a frustrating. My comment was that if you did want to try to handle the catchable exceptions inside your batchable if you don't re-throw the exception the problem won't appear in the AsyncApexJob and so give anyone looking there the impression that everything was fine when it wasn't. I'll add a PS to the answer to illustrate what re-throw means.
    – Keith C
    Commented Feb 29, 2016 at 10:11
  • Using this code, Can I view the error when I query the AsyncApexJob inside my finish method ? I am still studying how it works.
    – Hope
    Commented Feb 29, 2016 at 10:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .