« OWB and Oracle Workflow - going forwards | Main | Manual intervention in a process flow (restart, retry or reroute): Part I »

Mailing Map Errors

Sending mail from map or process flow activities often pops up in questions. The OWB process flow designer has a mail activity that makes sending a mail simple, you may find this inadequate if so, sending mail from the Oracle database is fairly simple, googling around you can find all kinds of stuff (here is one example). When I was trying this out I tried both approaches.

From within a process flow the simplest way I found to get all errors (possible errors initializing activity parameters for map and the map execution itself) is to have a custom function that takes the process flow execution id which you can get from a global OWB variable and pass the name of the flow and the name of the activity in order to query the OWB audit tables (it is not great passing names, but you will get all error types). I have created a simple function which also takes a boolean indicating the format (using HTML or plain text) and will return a string which will be the email body, it can return plain text or HTML formatted text. The OWB mail activity supports a text body, the example I google'd (see SQL here) has both text and HTML.

Here is the code for the function I used in the process flow;

create or replace function GET_ACTIVITY_ERRORS(
    FLOW_AUDIT_ID IN NUMBER, 
    PROCESS_FLOW_NAME IN VARCHAR2,
    ACTIVITY_NAME IN VARCHAR2,
    HTML_RESULT IN BOOLEAN DEFAULT false)
RETURN VARCHAR2    IS
cursor cAllErrors is
  select to_char(p.created_on, 'HH:MM:SS DD-MON-YY') || ' '||
  p.execution_audit_id || ' '||
  p.message_text  AuditText
  from all_rt_audit_exec_messages p
  where execution_audit_id in (
   select max(execution_audit_id)
    from all_rt_audit_executions a
    where a.parent_execution_audit_id=FLOW_AUDIT_ID
    and a.execution_name=PROCESS_FLOW_NAME||':'||ACTIVITY_NAME);

errorText VARCHAR2(4000) := 'Error in activity '|| ACTIVITY_NAME || ' : ' || chr(10) || chr(10) ;

BEGIN
    if (html_result) then
      errorText := '<br><b><u>Error in activity '|| ACTIVITY_NAME || ' : </u></b><br>' || chr(10) || chr(10) ;
    end if;
    FOR aerr in cAllErrors LOOP
      if (html_result) then
        errorText := errorText || '<br>  ' || aerr.AuditText || '</br>' || chr(10);
      else
        errorText := errorText || '  ' || aerr.AuditText || chr(10);
      end if;
    END LOOP;
    RETURN errorText;
    EXCEPTION
        WHEN OTHERS THEN
            return errorText;  -- return whatever is in the buffer
    RETURN NULL;
END;

This function is used in the flow using the OWB email activity and in the version which will send HTML formatted emails, I use the boolean to get HTML tokens in the result. With this function I'll get errors such as UK violations when executing the map or issues initializing the parameters for the map such as date format issues (say there was an expression during the evaluation of the mapping activity input parameter representing load date).

The basic process flow has a mapping activity that has a transition for success, all other error paths (activity initiation errors, execution warnings and execution errors) go through the mail path. I tried using the assign activity rather than the transformation activity to get the string representing the email body, I preferred the transformation activity - when an assign activity uses a custom transformation, you will have to qualify the function with the schema since the OWB code does an ALTER SESSION SET CURRENT_SCHEMA to the OWB control center so that the OWB code that the assign implementation references will be resolved. Not exactly good for everyone using it having to hard-code schema names, that's after having setup the evaluation location for the flows. So the transformation activity was used. The output of the function is bound to a variable named EMAIL_BODY. The variable is used in the email activity.

Mail Flow:

The transformation activity that retrieves the error codes has a parameter which the flow audit id, the OWB global variable PARENT_AUDIT_ID is passed into this parameter, I've set the literal value to false, since this is an expression that needs evaluated.

Mail Flow Audit Id:

The output of the function is stored in the process flow variable EMAIL_BODY, you can assign the result of the function to the variable by binding the output parameter GET_ACTIVITY_ERRORS to the variable;

Mail Flow Body:

This version of the flow sends a plain simple text email with the audit details;

Mail OWB 1:

If we use the PLSQL procedure that sends HTML content we can get richer emails using all of the HTML controls we need, so the new flow uses the send html mail PLSQL procedure and alters the HTML_RESULT parameter to GET_ACTIVITY_ERRORS.

Mail Flow Xform:

With this approach we can do all kinds of formatting, tables and linking. Here is the output with bold and underlying HTML;

Mail OWB 2:

If you need any manual intervention there are 2 mechanisms, using the notification activity which is an elaborate mechanism which relies on the workflow notification, there is also a manual activity that pauses the flow and allows manual intervention which can be performed in the repository browser using the activity expedite, more to come on this.....


TrackBack

TrackBack URL for this entry:
http://blogs.oracle.com/mt/mt-tb.cgi/2222

Comments (5)

Dave Katz:

I'm having trouble trying to implement this-- when I try to pass PARENT_AUDIT_ID to the transformation param FLOW_AUDIT_ID, I get the error "identifier 'PARENT_AUDIT_ID' must be declared." I made sure to set literal=false when defining the param value. I am also referencing PARENT_AUDIT_ID in the subject line of my email (SUBJECT = 'Process Flow Error (Audit_ID '||PARENT_AUDIT_ID||')' ) and it works fine there.

Jurgen:

I heve some problems with passing the global variable. I get followin errors in RAB:


RPE-01038: Failed to evaluate expression declare l_expression NUMBER := PARENT_AUDIT_ID;begin :result := to_char(l_expression);end;. Please modify the expression, redeploy and retry again.

ORA-06550: line 1, column 34: PLS-00201: identifier 'PARENT_AUDIT_ID' must be declared ORA-06550: line 1, column 24: PL/SQL: Item ignored ORA-06550: line 1, column 77: PLS-00320: the declaration of the type of this expression is incomplete or malformed ORA-06550: line 1, column 58: PL/SQL: Statement ignored

David Allan:

Do you have the property 'literal' set to false and the workflow user in OWB defined as a target user?

Jurgen:

"yes" to both questions. I checked what Dave did: use it in an email subject and it works ok there for me to...so I'm in the same situation as Dave.

julian:

What would be the recommended way to report on any error that occurred earlier, i.e. for a flow with sub-processes and numerous mappings? I am thinking about just including get_activity_errors at the end of the flow.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)