ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Using a HANDLER in WMB v6 for non-DB errors...

Post new topic  Reply to topic
 Using a HANDLER in WMB v6 for non-DB errors... « View previous topic :: View next topic » 
Author Message
UnclDanMan
PostPosted: Wed Nov 08, 2006 1:14 pm    Post subject: Using a HANDLER in WMB v6 for non-DB errors... Reply with quote

Newbie

Joined: 25 Jul 2006
Posts: 6

Hi all,

Two related questions...

Does anybody know if you can define an error handler for non database errors/exceptions? It looks like you declare an error handler based on SQLSTATE - is there a SQLSTATE created if you have math exceptions or string parsing exceptions, etc?

Also does anyone know if you can refer to variables that are declared elsewhere in your compute node from inside a handler block? I seem to be getting compiler warnings in the toolkit telling me that variables are not declared... But what I want to do in the handler situation requires visibility of those variables.

I don't know if I've misread the documentation or if there's a bug - but I think you're supposed to be able to write a handler to deal with any problem - and I assume you should have visibility into all your local variables from inside that handler...

Thoughts?

--Daniel
_________________
--Daniel Max Kestin
Back to top
View user's profile Send private message
mgk
PostPosted: Wed Nov 08, 2006 2:15 pm    Post subject: Reply with quote

Padawan

Joined: 31 Jul 2003
Posts: 1642

Hi,

Quote:
anybody know if you can define an error handler for non database errors/exceptions?


Yes you can, see topic ak17990 (SQLSTATE) for a list of currently defined states.

Quote:
anyone know if you can refer to variables that are declared elsewhere in your compute node from inside a handler block


You can refer to variables that are currently in scope. This means that they must be either declared in the handler itself, or in a containing scope before the handler block or at the Module level. For example, in this code:

Code:
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN

   SET OutputRoot.MQMD = InputRoot.MQMD;
   DECLARE x INT 1;
   
   SET OutputRoot.XMLNSC.TOP.X.Before = x;

   BEGIN
    DECLARE CONTINUE HANDLER FOR SQLSTATE LIKE'%'
    BEGIN
      SET x = 42;
      -- SET y = 12;
      SET OutputRoot.XMLNSC.TOP.SQLSTATE = SQLSTATE;
    END;

   -- DECLARE y INT 56;

    SET x = x/0;

   END;

   SET OutputRoot.XMLNSC.TOP.X.After = x;
 
END;


The variable x is in scope and can be used in the handler block as shown. However, the commented out variable y is not inscope and so cannot be used inside the handler block.

The output from this code is:

Code:
<TOP><X><Before>1</Before><After>42</After></X><SQLSTATE>S22012</SQLSTATE></TOP>


Which shows the SQLSTATE generated for a divide by zero error.


Regards,
_________________
MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions.
Back to top
View user's profile Send private message
UnclDanMan
PostPosted: Fri Nov 10, 2006 1:12 pm    Post subject: Hmmm...but the handler doesn't see XML parsing errors Reply with quote

Newbie

Joined: 25 Jul 2006
Posts: 6

Thanks - your code was really helpful - but I'm still not sure about all the SQLSTATES...

(Apparently BTW - and it's not clear from the documentation - you NEED to declare an extra BEGIN AND END block around the code that will use your handler (this is equivelant to a Java Try/Catch). You cannot just rely on the BEGIN and END block that's in your compute node.)

See the code sample below (which btw is taking the Hex Blob out of a MQWf error message - and converting it back into readable XML we can see what original message caused MQWf to cough up the error).

From what we can tell - the handler is never invoked when there is an XML parsing error in the " CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet); " statement. If the hexBlob there has bad XML in it - the exception immediately just bubbles out backwards to the nearest catch terminal - and then we have to reroute it to a second compute node to do the error processing. It just seems wasteful. We should be able to do this inside the one compute node.

Does anybody know if that's a bug in the broker or if we're doing anything wrong?

--Daniel

Code:
-- This will Parse the blob and create the XML format for output.
-- The CCSID will tell it to parse as EBCDIC or ASCII.
-- If the hex decodes as invalid XML, it will throw an exception and go to the catch of the try/catch.
BEGIN

  DECLARE CONTINUE HANDLER FOR SQLSTATE LIKE'%'
  BEGIN
    -- Wrap the newly formed string in a CDATA tag so the XML parser doesn't look at the invalid message.
    -- This will prevent the xml parser from throwing an error.
    -- (when you cast a string as a blob, you can specify a CCSID and it will convert to hex)
    SET hexBlob = CAST('<InvalidXML><![CDATA[' AS BLOB CCSID charSet) || hexBlob || CAST(']]></InvalidXML>' AS BLOB CCSID charSet);               
    -- Parse the now valid message which is of this format, and should not throw an error.
    --  <Tag>
    --          <![CDATA[
    --                  <INVALID><XML>data</XML></MESSAGE> (not parsed because it is in a CDATA tag)
    --          ]]>
    --  </Tag>
    CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet);
  END;

  CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet);           
END;

_________________
--Daniel Max Kestin
Back to top
View user's profile Send private message
michaelpatton
PostPosted: Wed Nov 15, 2006 6:49 pm    Post subject: Reply with quote

Apprentice

Joined: 21 May 2002
Posts: 25
Location: East Coast USA

Looking at your ESQL, I see the following, (I added some code to build a testcase on this)

-- This will Parse the blob and create the XML format for output.
-- The CCSID will tell it to parse as EBCDIC or ASCII.
-- If the hex decodes as invalid XML, it will throw an exception
-- and go to the catch of the try/catch.
SET OutputRoot.Properties = InputRoot.Properties;
SET OutputRoot.MQMD = InputRoot.MQMD;

DECLARE charSet INTEGER;
DECLARE hexBlob BLOB;


SET charSet = CAST(InputRoot.Properties.CodedCharSetId AS INTEGER);
SET hexBlob = InputRoot.BLOB.BLOB;

BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE LIKE'%'
BEGIN
-- Wrap the newly formed string in a CDATA tag so the XML parser
-- doesn't look at the invalid message.
-- This will prevent the xml parser from throwing an error.
-- (when you cast a string as a blob, you can specify a CCSID and
-- it will convert to hex)
SET hexBlob = CAST('<InvalidXML><![CDATA[' AS BLOB CCSID charSet)
|| hexBlob || CAST(']]></InvalidXML>' AS BLOB CCSID charSet);
-- Parse the now valid message which is of this format, and should
-- not throw an error.
-- <Tag>
-- <![CDATA[
-- <INVALID><XML>data</XML></MESSAGE>
-- (not parsed because it is in a CDATA tag)
-- ]]>
-- </Tag>
CREATE LASTCHILD OF OutputRoot DOMAIN('XML')
PARSE(hexBlob CCSID charSet);
END;
CREATE LASTCHILD OF OutputRoot DOMAIN('XML')
PARSE(hexBlob CCSID charSet);
END; -- HANDLER BLOCK
END;


In the code that is called to convert the BLOB to XML, the PARSE is not instructed to check the validity of the resulting XML. Therefore, the CREATE statement does not throw an exception at this point. You will need to tell the PARSE clause to ensure that the data that is parsed into XML is indeed well formed XML before it propagates it on its way.

This is accomplished through the OPTIONS clause of the PARSE clause. (Sounds redundant... sorry)

First, early in the ESQL, preferably before the HANDLER Clause, the simplest solution is to declare an options variable.

DECLARE parseOptions INTEGER BITOR(RootBitStream,ValidateComplete);

Then, you will need to change the CREATE Statement to use this parseOptions variable.

CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet OPTIONS parseOptions);

This will tell the PARSER to validate immediately, and not at some later point in the flow, that the XML that has been parsed in indeed well formed XML.

The Code
Code:

   CREATE PROCEDURE Test_Two() BEGIN
   -- This will Parse the blob and create the XML format for output.
   -- The CCSID will tell it to parse as EBCDIC or ASCII.
   -- If the hex decodes as invalid XML, it will throw an exception
                -- and go to the catch of the try/catch.
    SET OutputRoot.Properties = InputRoot.Properties;
   SET OutputRoot.MQMD = InputRoot.MQMD;
   
   DECLARE charSet INTEGER;
   DECLARE hexBlob BLOB;
   DECLARE parseOptions INTEGER BITOR(RootBitStream,ValidateComplete);

   
   SET charSet = CAST(InputRoot.Properties.CodedCharSetId AS INTEGER);
   SET hexBlob = InputRoot.BLOB.BLOB;
   
   BEGIN
      DECLARE CONTINUE HANDLER FOR SQLSTATE LIKE'%'
      BEGIN
          -- Wrap the newly formed string in a CDATA tag so the XML parser doesn't look at the invalid message.
          -- This will prevent the xml parser from throwing an error.
          -- (when you cast a string as a blob, you can specify a CCSID and it will convert to hex)
          SET hexBlob = CAST('<InvalidXML><![CDATA[' AS BLOB CCSID charSet) || hexBlob || CAST(']]></InvalidXML>' AS BLOB CCSID charSet);               
          -- Parse the now valid message which is of this format, and should not throw an error.
          --  <Tag>
          --          <![CDATA[
          --                  <INVALID><XML>data</XML></MESSAGE> (not parsed because it is in a CDATA tag)
          --          ]]>
          --  </Tag>
          CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet OPTIONS parseOptions);
      END;
      CREATE LASTCHILD OF OutputRoot DOMAIN('XML') PARSE(hexBlob CCSID charSet OPTIONS parseOptions);               
      END; -- HANDLER BLOCK
   END;

Back to top
View user's profile Send private message Yahoo Messenger
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Using a HANDLER in WMB v6 for non-DB errors...
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.