Solved

Re-work exception handling

Posted on 2009-05-13
14
172 Views
Last Modified: 2012-05-11
Can somebody rework the exception handling in this code. I can't quite get it right...

RSSXML and RSSXML2 are IXMLDOMDocumetn2 instances created earlier in the code and used in ParseFeed
to parse out the info.

What is happening is that the first exception is being raised because RSSXML.documentElement is going to be nil. It goes into the finally, as expected, but then when tracing, it goes back to this line:
  oMainChannelNode := RSSXML.SelectSingleNode('rss').FirstChild;

procedure TRSSFrame.GetFeed;

var

  oChannelNode:     IXMLDOMNode;

  oMainChannelNode: IXMLDOMNode;

  oItemNodes:       IXMLDOMNodeList;

  i:                Integer;

begin

  SL := TStringList.Create;

  try

    SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat1No+'&feed=rss2');

    // Deliberately setting SL.Text = '' to check exception handling

    SL.Text := '';

    RSSXML.loadXML(SL.Text);

    if not Assigned(RSSXML.documentElement) then

      raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat1]);
 

    oMainChannelNode := RSSXML.SelectSingleNode('rss').FirstChild;

    if Assigned(oMainChannelNode) then

    begin

      SL.Clear;

      if sCat2No <> '' then

      begin

        SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat2No+'&feed=rss2');

        RSSXML2.loadXML(SL.Text);

        if not Assigned(RSSXML2.documentElement) then

          raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat2]);
 

        oChannelNode := RSSXML2.SelectSingleNode('rss').FirstChild;

        oItemNodes   := oChannelNode.selectNodes('//item');

        for i := 0 to oItemNodes.Length-1 do

          oMainChannelNode.appendChild(oItemNodes.item[i]);

      end;

      SL.Clear;

      if sCat3No <> '' then

      begin

        SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat3No+'&feed=rss2');

        RSSXML2.loadXML(SL.Text);

        if not Assigned(RSSXML2.documentElement) then

          raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat3]);
 

        oChannelNode := RSSXML2.SelectSingleNode('rss').FirstChild;

        oItemNodes   := oChannelNode.selectNodes('//item');

        for i := 0 to oItemNodes.Length-1 do

          oMainChannelNode.appendChild(oItemNodes.item[i]);

      end;

    end;

  finally

    SL.Free;

    ParseFeed; // This parses the XML in the RSSXML document

  end; //try

end;

Open in new window

0
Comment
Question by:EddieShipman
  • 9
  • 5
14 Comments
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24379715
there is no exception handling here, just raising exceptions
no
try
except
end;

or am i missing something ?
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 24379990
Well, could you rework it?
I'm having a whale of a time getting it correct and the posted code is not working correctly.
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24380028
which exception is the one you want to see raised ?
and why ?
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24380034
maybe your assuming something, and i heard in a film once
assumptions are the mother of all f*ck*ps ...
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24380166
to see where it jumps out as a last resort i usually add a identifier and some logging
and a wrapping try finally with showing the log

this way you can trace where the function goes
every level should have a different letter, to see if it actually goes into that level
procedure TRSSFrame.GetFeed;

var 

  M, Msg: string; 

  X: Integer;

  procedure Jump(aMsg: string = '');

  begin

    if aMsg <> '' then 

      M := aMsg; 

    Inc(X);

    Msg := Msg + M + IntToStr(X) + #13#1O;

  end;

var

  oChannelNode:     IXMLDOMNode;

  oMainChannelNode: IXMLDOMNode;

  oItemNodes:       IXMLDOMNodeList;

  i:                Integer;

begin

  X := 0;

  Msg := '';

  try

    SL := TStringList.Create;

    try

      Jump('A');

      SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat1No+'&feed=rss2');

      Jump;

      // Deliberately setting SL.Text = '' to check exception handling

      SL.Text := '';

      Jump;

      RSSXML.loadXML(SL.Text);

      Jump;

      if not Assigned(RSSXML.documentElement) then

        raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat1]);

      Jump;    

      oMainChannelNode := RSSXML.SelectSingleNode('rss').FirstChild;

      Jump;

      if Assigned(oMainChannelNode) then

      begin

        Jump('B');

        SL.Clear;

        Jump;

        if sCat2No <> '' then

        begin

          Jump('C');

          SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat2No+'&feed=rss2');

          Jump;

          RSSXML2.loadXML(SL.Text);

          Jump;

          if not Assigned(RSSXML2.documentElement) then

            raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat2]);

          Jump;

          oChannelNode := RSSXML2.SelectSingleNode('rss').FirstChild;

          Jump;

          oItemNodes   := oChannelNode.selectNodes('//item');

          Jump;

          for i := 0 to oItemNodes.Length-1 do

            oMainChannelNode.appendChild(oItemNodes.item[i]);

          Jump;

        end;

        Jump;

        SL.Clear;

        Jump;

        if sCat3No <> '' then

        begin

          Jump('D'); 

          SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat3No+'&feed=rss2');

          Jump;

          RSSXML2.loadXML(SL.Text);

          Jump;

          if not Assigned(RSSXML2.documentElement) then

            raise EXMLLoadingException.CreateFmt('RSS Feed for Category %s did not load properly.', [sCat3]);

          Jump;   

          oChannelNode := RSSXML2.SelectSingleNode('rss').FirstChild;

          Jump;

          oItemNodes   := oChannelNode.selectNodes('//item');

          Jump;

          for i := 0 to oItemNodes.Length-1 do

            oMainChannelNode.appendChild(oItemNodes.item[i]);

          Jump;

        end;

      end;

    finally

      Jump('E');

      SL.Free;

      Jump;

      ParseFeed; 

      Jump;// This parses the XML in the RSSXML document

    end; //try

  finally

    Jump('F');

    ShowMessage(Msg);

  end;

end;

Open in new window

0
 
LVL 26

Author Comment

by:EddieShipman
ID: 24380210
I already know where it goes.
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24380248
>> as expected, but then
this means you don't know why or are missing out on something or making an assumption ... ?
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 26

Author Comment

by:EddieShipman
ID: 24384572
I understand that it is supposed to go into the finally after the exception is raised, (AS EXPECTED)
But then why it goes BACK to the next line, I don't understand that.
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24384585
it shouldn't ...
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24384595
do you have more than 1 copy of the .pas file ?
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 24385846
nope.
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24392382
why this :
finally
    SL.Free;
    ParseFeed; // This parses the XML in the RSSXML document
  end; //try
end;

and not, (if you raised an exception, you still want to run ParseFeed ???)
  finally
    SL.Free;
  end; //try
  ParseFeed; // This parses the XML in the RSSXML document
end;
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 24395201
We've kind of worked it out like that.

procedure TAccuBuildRSSFrame.GetFeed;

var

  oChannelNode:     IXMLDOMNode;

  oRSSNode:         IXMLDOMNode;

  oMainChannelNode: IXMLDOMNode;

  oItemNodes:       IXMLDOMNodeList;

  i:                Integer;

  bParse:           Boolean;

begin

  LockWindowUpdate(RSSPanel.Handle);

  SL := TStringList.Create;

  bParse := False;

  try

    try

      SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat1No+'&feed=rss2');

      RSSXML.loadXML(SL.Text);

      oRSSNode := RSSXML.SelectSingleNode('rss');

      oMainChannelNode := oRSSNode.FirstChild;

      if Assigned(oMainChannelNode) then

      begin

        SL.Clear;

        if sCat2No <> '' then

        begin

          SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat2No+'&feed=rss2');

          RSSXML2.loadXML(SL.Text);

          oRSSNode := RSSXML2.SelectSingleNode('rss');

          oChannelNode := oRSSNode.FirstChild;

          if Assigned(oChannelNode) then

          begin

            oItemNodes   := oChannelNode.selectNodes('//item');

            for i := 0 to oItemNodes.Length-1 do

              oMainChannelNode.appendChild(oItemNodes.item[i]);

            bParse := True;

          end;

        end;

        SL.Clear;

        if sCat3No <> '' then

        begin

          SL.Text := FHTTP.Get('http://www.our-site.com/blog/?cat='+sCat3No+'&feed=rss2');

          RSSXML2.loadXML(SL.Text);

          oRSSNode := RSSXML2.SelectSingleNode('rss');

          oChannelNode := oRSSNode.FirstChild;

          if Assigned(oChannelNode) then

          begin

            oItemNodes   := oChannelNode.selectNodes('//item');

            for i := 0 to oItemNodes.Length-1 do

              oMainChannelNode.appendChild(oItemNodes.item[i]);

            bParse := True;

          end;

        end;

      end;

    except

      on e:Exception do

      begin

        ShowMessage('There was a problem loading the RSS Feed.');

        bParse := False;

      end;

    end;

  finally

    SL.Free;

    oChannelNode     := nil;

    oRSSNode         := nil;

    oMainChannelNode := nil;

    oItemNodes       := nil;

  end; //try

  if bParse then

    ParseFeed;

end;

Open in new window

0
 
LVL 36

Accepted Solution

by:
Geert Gruwez earned 500 total points
ID: 24395230
it's not normal for a finally to jump back into the code .
i'm boggled at this.

i had this some times when creating a copy of the file,
opening an old file, and then compiling.
Because the current directory was looking at the old file, the old file got compiled.

that's why i asked if you had any duplicates ...

but this is something very suspiciously buggy ...
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now