# ON ERROR / END-ERROR Question

**URL:** <https://techcommunity.softwareag.com/t/on-error-end-error-question/62330>\
**Category:** Forum\
**Tags:** Adabas-Natural, Natural, Natural-on-Mainframes\
**Created:** [June 21, 2007, 3:02am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330 "2007-06-21T03:02:06Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![thespin](https://avatars.discourse-cdn.com/v4/letter/t/8c91f0/32.png) [@thespin](https://techcommunity.softwareag.com/u/thespin)\
**Post date:** [June 21, 2007, 3:02am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/1 "2007-06-21T03:02:06Z")

</div>

Hello amigos,

There appears to be some contradiction in the documentation on ‘ON ERROR’ here:  
file:///C:/Download/Mainframe/Natural%20421%20Document/sm/onerror\_0910.htm#ON\_ERROR\_Processing\_within\_Subroutines

On the one hand, it states:  
“When the ON ERROR statement block is entered for execution, the normal flow of program execution has been interrupted and cannot be resumed …” AND “Only one ON ERROR statement is permitted in a Natural object.”

On the other hand:  
"When a subroutine structure is built by using CALLNAT, PERFORM or FETCH RETURN, each module may contain an ON ERROR statement.

When an error occurs, Natural will automatically trace back the subroutine structure and select the first ON ERROR statement encountered in a subroutine for execution."  
AND  
“Exiting from an ON ERROR Block:  
An ON ERROR block may be exited by using a FETCH, STOP, TERMINATE, RETRY or ESCAPE ROUTINE statement. If the block is not exited using one of these statements, standard error message processing is performed and program execution is terminated.”

I am trying to trap a duplicate key on STORE error in a PERFORMed subroutine and continue processing. Is that possible ?

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![Ralph\_Zbrog](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/ralph_zbrog/32/78_2.png) [@Ralph\_Zbrog](https://techcommunity.softwareag.com/u/Ralph_Zbrog)\
**Post date:** [June 21, 2007, 5:33am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/2 "2007-06-21T05:33:26Z")

</div>

Is it possible to continue an application after an ON ERROR? Technically, yes. But scenarios in which this procedure would apply are so rare that I don’t even consider it. Few applications are simple enough to allow you to determine where you were, logically, at the time of the error. You need to know the values of all variables and globals, the contents of all views, which code to execute, which code to circumvent, …

Since you’re in a subroutine at the time, I’d say this is a lost cause.

---

<div class="post-metadata">

**Author:** ![Finn\_the\_Dane](https://avatars.discourse-cdn.com/v4/letter/f/c57346/32.png) [@Finn\_the\_Dane](https://techcommunity.softwareag.com/u/Finn_the_Dane)\
**Post date:** [June 21, 2007, 5:44am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/3 "2007-06-21T05:44:36Z")

</div>

Hi Thespin,  
I would suggest a subprogram containing the store statement  
and then an On ERROR that sets an error msg in the parm area.  
Remember to have an escape routine in the ON-EROR block or the standard errorhandling of the caller or the standard \*ERROR-TA wil take control.  
Finn

ON ERROR  
move ‘DUPLICATE KEY’ to ERR-MSG  
move 99 to ERR-NO  
escape routine  
END-ERROR

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [June 21, 2007, 6:02am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/4 "2007-06-21T06:02:48Z")

</div>

How about simply placing a FIND NUMBER before the STORE? If \*NUMBER is already GT zero, you know you have a problem. You could write a workfile with all sorts of data to find the bug. Then, your program could, perhaps, simply continue without doing the STORE.

Of course, program logic may still be a problem. Proceed with caution.

steve

---

<div class="post-metadata">

**Author:** ![Matthias1](https://avatars.discourse-cdn.com/v4/letter/m/9fc348/32.png) [@Matthias1](https://techcommunity.softwareag.com/u/Matthias1)\
**Post date:** [June 21, 2007, 3:04pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/5 "2007-06-21T15:04:58Z")

</div>

> [@Ralph Zbrog](#):
>
> Is it possible to continue an application after an ON ERROR? Technically, yes. But scenarios in which this procedure would apply are so rare that I don’t even consider it.

It makes sence to continue an application in case of a NAT3145. For this you got the statement RETRY. All other statements to leave the ON ERROR Block leave the module as well.

Of course you can consider a FETCH-FETCH technique for this. But I think this is not a proper way. For example program1 reads:

```auto
ON ERROR
FETCH 'PROGRAM2'
END-ERROR
```

And Program2:

```auto
ON ERROR
FETCH 'PROGRAM1'
END-ERROR
```

---

<div class="post-metadata">

**Author:** ![thespin](https://avatars.discourse-cdn.com/v4/letter/t/8c91f0/32.png) [@thespin](https://techcommunity.softwareag.com/u/thespin)\
**Post date:** [June 21, 2007, 11:16pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/6 "2007-06-21T23:16:37Z")

</div>

Thanks all for your responses.

The program copies tens of thousands of records from an archive. There may be less than 1 duplicate per 10,000 records. I wanted to avoid the overhead of reading before writing every record but that’s what I went with as the simplest and cleanest way.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [June 22, 2007, 1:01am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/7 "2007-06-22T01:01:35Z")

</div>

"I wanted to avoid the overhead of reading before writing every record "

Trivial point, but, HISTOGRAM and FIND NUMBER for a single value of a single key, do not read records. And, if you are doing this in sequence by the key, i/o to the inverted tables is minimized since Adabas will often find the appropriate info in memory.

steve

---

<div class="post-metadata">

**Author:** ![thespin](https://avatars.discourse-cdn.com/v4/letter/t/8c91f0/32.png) [@thespin](https://techcommunity.softwareag.com/u/thespin)\
**Post date:** [June 22, 2007, 2:03am UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/8 "2007-06-22T02:03:47Z")

</div>

Trivial is as trivial does. 🙂

True, only the indeces are being read. But it’s unclear how many will end up being read since there are 100s of thousands of records already on the output file and the records being stored are interspersed by key.

---

<div class="post-metadata">

**Author:** ![Matthias1](https://avatars.discourse-cdn.com/v4/letter/m/9fc348/32.png) [@Matthias1](https://techcommunity.softwareag.com/u/Matthias1)\
**Post date:** [June 22, 2007, 3:37pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/9 "2007-06-22T15:37:30Z")

</div>

> [@thespin](#):
>
> I wanted to avoid the overhead of reading before writing every record but that’s what I went with as the simplest and cleanest way.

Then pack your store into a Subprogram. There you can put an ON ERROR Block which returns the NAT-Error-Number to the calling program.

---

<div class="post-metadata">

**Author:** ![Klaus\_Sponagel](https://avatars.discourse-cdn.com/v4/letter/k/3bc359/32.png) [@Klaus\_Sponagel](https://techcommunity.softwareag.com/u/Klaus_Sponagel)\
**Post date:** [June 22, 2007, 4:44pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/10 "2007-06-22T16:44:21Z")

</div>

With a ESCAPE ROUTINE in a ON ERROR clause you can intercept any Natural errors. Only if the program flow reaches the END-ERROR the error is percolated to the program caller.  
Here is a sample how you can continue your processing:

```auto

0010 READ TONS OF RECORDS
0020 CALLNAT 'STOREREC' #RECORD #ERROR-NR
0030 IF #ERROR-NR NE 0
0040 IF #ERROR-NR = 3145 ESCAPE TOP END-IF
0050 STOP
0060 END-IF  
0070 END-READ  
0080 END
```

and the subprogram

```auto

0010 DEFINE DATA PARAMETER
0020 1 #RECORD
0030 1 #E_NUMBER(P4)
0040 END-DEFINE
0050 ON ERROR
0060 #E_NUMBER := *ERROR-NR
0070 ESCAPE ROUTINE
0080 END-ERROR
0090 
0100 STORE RECORD
0110 END
```

I hope this helps  
Klaus

---

<div class="post-metadata">

**Author:** ![thespin](https://avatars.discourse-cdn.com/v4/letter/t/8c91f0/32.png) [@thespin](https://techcommunity.softwareag.com/u/thespin)\
**Post date:** [June 22, 2007, 6:20pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/11 "2007-06-22T18:20:19Z")

</div>

What a great group of people!

Thanks again.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/techcommunity/original/3X/c/d/cd19967bb605d28a72d77eb83a1cae22f3df2eb8.svg) [@system](https://techcommunity.softwareag.com/u/system)\
**Post date:** [April 2, 2021, 2:41pm UTC](https://techcommunity.softwareag.com/t/on-error-end-error-question/62330/12 "2021-04-02T14:41:15Z")

</div>


