Handling exceptions

Post questions here relative to DataStage Server Edition for such areas as Server job design, DS Basic, Routines, Job Sequences, etc.

Moderators: chulett, rschirm, roy

Post Reply
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Handling exceptions

Post by RodBarnes »

Up til now, I've been using explicit notification stages tied via a trigger to the major job activities. I now have a good understanding of triggers and notifications. :)

I've been looking at ways to improve the error handling. I believe using an exception handler may allow me to avoid using explicit notifications and rely upon a single notification tied to the exception that simply notifies me of the stage that failed using the exception handler properties.

But my attempts to use it don't seem to work. I understand the structure (I think) and have made the exception handler a separate path:

Code: Select all

Job1 --> Job2 --> Job3 --> etc...

ExceptionHandler --> Notify
But no notification occurs even when I force an abort using an invalid table name or something.

I've tried it with "Automatically handle activities that fail" both enabled and disabled but saw no difference. (I'm not clear on the relationship of this option in conjunction with using an exception handler.)

Feedback is appreciated. Maybe there are books or additional documentation that may help me better understand the exception handler usage?

Thanks.
Krazykoolrohit
Charter Member
Charter Member
Posts: 560
Joined: Wed Jul 13, 2005 5:36 am
Location: Ohio

Post by Krazykoolrohit »

Are your exception handler and the jobs connected?

Just ensuring.
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Post by RodBarnes »

Krazykoolrohit wrote:Are your exception handler and the jobs connected?
Ummm.... No. :? There doesn't seem to be anyway to link them together as the handler only supports an output link. And from reading other threads on this forum, my understanding is that they are NOT linked together but that the handler catches anything that the explicit triggers between stages do NOT catch.
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Post by RodBarnes »

Well, not sure what was happening before but.... In the interest of continuity, I'll include what I found worked:

I got it to work. I have the sequence set to "Automatically handle activities that fail" and a model like this:

Code: Select all

JobTest --OK--> NotifyOk

ExceptionHandler ----> NotifyFail
And it does exactly what I expected. :wink:

To clarify, there is no link between the exception handler and the job stage. It just seems to catch all the other events from the job stage that are not explicitly handled. I also understand that an exception handler is not required unless I want it to take some action upon an exeption; e.g., send an email.
Krazykoolrohit
Charter Member
Charter Member
Posts: 560
Joined: Wed Jul 13, 2005 5:36 am
Location: Ohio

Post by Krazykoolrohit »

cool.
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

Help for the job sequence properties is clear on how the compilation options work. It depends on whether an Exception Handler exists and on whether explicit handling (what you used to have) exists.
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Post by RodBarnes »

ray.wurlod wrote:Help for the job sequence properties is clear on how the compilation options work.
Yes, it is. The issue was that there is nothing that decribes the interrelationship between this setting and an exception handler. Does the handler work with the setting (it is enabled), or does it replace the automatic handling (it is disabled). In my initial tests it was not generating a notification in either case so it was unclear.

But the subsequent tests worked and I now have it running correctly as noted in my previous message. (As usual, soon after posting the original message, I figured out how to get it to work. Though I am still not sure why it initially wasn't working. :( )

Thanks for taking the time to reply.
Last edited by RodBarnes on Tue Jul 11, 2006 12:12 pm, edited 1 time in total.
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Post by RodBarnes »

I do have a follow-up question related to using an exception handler, though: Is there a way to get the log entries into the body of an email?

My exception handler links to a notification and I have the option set to "Include job status in email". But this only includes the results -- the status, start time, end time, and subsequent actions taken like attempt to clean-up, etc. It doesn't actually include the error message from the host. I still have to go view the log to actually see what caused the issue.
Krazykoolrohit
Charter Member
Charter Member
Posts: 560
Joined: Wed Jul 13, 2005 5:36 am
Location: Ohio

this will help. a code for your routine

Post by Krazykoolrohit »

edited as per ray's suggestion:

<CODE>

$INCLUDE DSINCLUDE DSD_STAGE.H
$INCLUDE DSINCLUDE JOBCONTROL.H
$INCLUDE DSINCLUDE DSD.H
$INCLUDE DSINCLUDE DSD_RTSTATUS.H

Deffun DSRMessage(A1, A2, A3) Calling "*DataStage*DSR_MESSAGE"
Equate RoutineName To "JobLogMail"

* Passing JobName for which log is to be seen

Call DSLogInfo("Job Name is ":JobName, RoutineName)

* Creating a Job Handle fot that particular job
JobHandle=DSAttachJob(JobName,DSJ.ERRNONE)

* Get The Start Time of job

StartTime=DSGetJobInfo(JobHandle,DSJ.JOBSTARTTIMESTAMP)
Call DSLogInfo("Start Time of job is ":StartTime, RoutineName)

* Get The End Time of job run

EndTime=DSGetJobInfo(JobHandle,DSJ.JOBLASTTIMESTAMP)
Call DSLogInfo("Start Time of job is ":EndTime, RoutineName)

*Get the job log for the run between start and end times.

SummaryArray = DSGetLogSummary(JobHandle, DSJ.LOGANY, StartTime, EndTime,0)

* -----------------------------------------------------------------
* Decription: Get last warning.
* -----------------------------------------------------------------
* Notes:
* -----------------------------------------------------------------
Ans = ''
* -----------------------------------------------------------------
* initialize standard variables
* -----------------------------------------------------------------
ProgId = 'KgdGetLastWarning'
CrLf = char(13) : char(10)
SearchStr = 'The value of the row is:'
LenSearchStr = len(SearchStr)
JobLogs = ''
ColumnNames = ''
Values = ''
ValLens = ''
open 'DS_JOBS' to DsJobsPtr else goto TheEnd
TextSw = @false
* -----------------------------------------------------------------
open 'DICT','RT_LOG' to DictRtLog then
read FullText from DictRtLog, "FULL.TEXT" then
TextSw = @true
end
end
RealJobName = JobName
if index(RealJobName, '.', 1)>0 then
RealJobName = field(JobName, '.', 1)
end
* -----------------------------------------------------------------
read JobRec from DsJobsPtr, RealJobName then
JobNo = JobRec<5>
FileName = 'RT_LOG':JobNo
* -----------------------------------------------------------------
open FileName to RT.LOG else goto TheEnd
* -----------------------------------------------------------------
Cmd = 'SSELECT ':FileName :' UNLIKE "//..." BY-DSND @ID '
if RealJobName <> JobName then
Cmd := ' AND WITH F5 LIKE ':JobName:'...'
end
execute Cmd capturing Output
Cnt = 0
* -----------------------------------------------------------------
loop while readnext RtLogId do
read RtLogRec from RT.LOG, RtLogId then
tmp = RtLogRec
TypeNo = RtLogRec<1>
EventTime = RtLogRec<3>
EventUser = RtLogRec<6>
EventType = 'Control'
* -----------------------------------------------------------------
begin case
case TypeNo = 1
EventType = 'Info'
case TypeNo = 2
EventType = 'Warning'
case TypeNo = 3
EventType = 'Fatal'
case TypeNo = 4
EventType = 'Reject'
case TypeNo = 5
EventType = 'Control'
case TypeNo = 6
EventType = 'Reset'
case TypeNo = 7
EventType = 'Error'
case TypeNo = 8
EventType = 'Debug'
end case
* -----------------------------------------------------------------
if TextSw then
@ID = fmt(RtLogId, "10'0'R")
@RECORD = RtLogRec
@RECCOUNT = 1
MSG.ARGS = RtLogRec<5>
MSG.TEXT = RtLogRec<10>
EventMsg = SUBR("*DataStage*DSR_MESSAGE", @ID, MSG.TEXT, RAISE(MSG.ARGS))
end else
EventMsg = lower(RtLogRec<10>)
EventMsg = change(EventMsg, '%s', JobName)
EventMsg = change(EventMsg, '%1', JobName)
end
EventMsg = change(EventMsg, char(13), '')
EventMsg = change(EventMsg, char(10), @VM)
NoOfLines = dcount(EventMsg, @VM)
EventMsgSave = EventMsg
EventMsg = trim(change(EventMsg, @VM, ' '))
EventMsg = lower(EventMsg)
* -----------------------------------------------------------------
if EventType = 'Warning' then
print 'RtLogId=':RtLogId
for i=1 to NoOfLines
print i 'R#5':'. ':EventMsgSave<1, i>
next i
print
print
Found = index(EventMsg, SearchStr, 1)
if Found > 0 then
MsgLine = trim(EventMsg[Found + LenSearchStr, len(EventMsg) - Found - LenSearchStr + 1])
convert '=' to @FM in MsgLine
NoOfLines = dcount(MsgLine, @FM)
for i=1 to NoOfLines
ThisLine = trim(MsgLine)
NoWords = dcount(ThisLine, ' ')
ColumnName = trim(field(ThisLine, ' ', NoWords))
NextLine = trim(MsgLine<i+1>)
NoWordsNext = dcount(NextLine, ' ')
Value = field(NextLine, ' ', 1, NoWordsNext-1)
Cnt += 1
ColumnNames<1, Cnt> = ColumnName
Values<1, Cnt> = Value
ValLens<1, Cnt> = len(Value)
next i
Ans = ColumnNames
Ans<2> = Values
Ans<3> = ValLens
goto TheEnd
end
end
* -----------------------------------------------------------------
tmp2 = ''
tmp2<1, 1> = RtLogId
tmp2<1, 2> = EventType
tmp2<1, 3> = EventTime
tmp2<1, 4> = EventUser
tmp2<1, 5> = EventMsg
* -----------------------------------------------------------------
JobLogs = tmp2 : @FM : JobLogs
* if Cnt >= 100 then goto TheEnd
end
repeat
end
* -----------------------------------------------------------------
NoOfLogs = dcount(JobLogs, @FM)
if trim(JobLogs<NoOfLogs, 1>) = '' then
del JobLogs<NoOfLogs, 1>
if trim(JobLogs<NoOfLogs-1, 1>) = '' then
del JobLogs<NoOfLogs-1, 1>
end
end
if trim(JobLogs<1, 1>) = '' then
del JobLogs<1, 1>
end
* -----------------------------------------------------------------
TheEnd:
CLEARSELECT ALL
for MvNo=1 to Cnt
print MvNo 'R#5':'. ':Ans<1, MvNo>:'(':Ans<3, MvNo>:') = ':Ans<2, MvNo>
next MvNo
* -----------------------------------------------------------------


Reply = DSSendMail("From: <sender mail id>\nTo:xxxx.xxxx@xx.com, \nSubject:"<subject>":JobName:"\nBody:":JobLogs)


Begin Case
Case Reply = DSJE.NOERROR
GoTo SuccessExit
Case @True
GoTo ErrorExit
End Case

SuccessExit:
ErrorCode = 0
GoTo NormalExit

ErrorExit:

ErrorCode = 1
GoTo NormalExit

NormalExit:

<CODE>
Last edited by Krazykoolrohit on Tue Jul 11, 2006 2:23 pm, edited 1 time in total.
RodBarnes
Charter Member
Charter Member
Posts: 182
Joined: Fri Mar 18, 2005 2:10 pm

Re: this will help. a code for your routine

Post by RodBarnes »

Thanks for the code. I'll check it out.
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

:P Yuk! Format the code (in DataStage) then edit the post with the code. Replace the code with the formatted code surrounded by Code tags.
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
Post Reply