Recent

Author Topic: [solved] How to catch error 400 ?  (Read 6125 times)

Nicole

  • Hero Member
  • *****
  • Posts: 1303
[solved] How to catch error 400 ?
« on: July 17, 2025, 10:24:59 pm »
Within a nicely running code, there is a problem with this line:

Code: Pascal  [Select][+][-]
  1.     try
  2.       Response := HttpClient.Get(URL);
    
The problem is: I can "try", but the error message is dropped and my except block never reached.

The error message, which is dropped with or without "try" reads,    
    
     [Debuggerausnahmen-Nachricht]
Code: Text  [Select][+][-]
  1. [Break]
  2. Projekt project_xxx hat Exception-Klasse »EHTTPClient« ausgelöst mit der Meldung:
  3. Unexpected response status code: 400
  4.  Bei Adresse 1004B1065
  5. [Diesen Ausnahmetyp übergehen]
  6. [Continue]

What can I do that the error-message is NOT shown to the user but passed on to my except block below?

Thank you all for that!!

« Last Edit: July 31, 2025, 07:20:41 pm by Nicole »

paule32

  • Hero Member
  • *****
  • Posts: 645
  • One in all. But, not all in one.
Re: How to catch error 400 ?
« Reply #1 on: July 17, 2025, 10:44:29 pm »
short Question => did you .CREATE ?
short Answer:
- you can not simply use TRY on Get Information's from a WebSite.
- you have to drop a AJAX Request (GET / POST)

- then you can handle the Request with the Result after getting Response of the Request
- this can be done by IF THEN ELSE or CASE Statement - but not simply per TRY - except, you use a Framework that supports Exception's
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

dbannon

  • Hero Member
  • *****
  • Posts: 3686
    • tomboy-ng, a rewrite of the classic Tomboy
Re: How to catch error 400 ?
« Reply #2 on: July 18, 2025, 01:52:19 am »
Is your issue related to the two things we expect from a 'try' ?  Handle the exception AND ensure resources are released. This works OK, its a copy and paste from my project with some unnecessary things stripped out for clarity  -

Code: Pascal  [Select][+][-]
  1. function TMistySync.Downloader(    URL : string; out SomeString : String;) : boolean;
  2. var
  3.     Client: TFPHTTPClient;
  4. begin
  5.     if DebugMode then debugln('TMistySync.Downloader URL is ' + URL);
  6.      Client := TFPHttpClient.Create(nil);
  7.     Client.AddHeader('User-Agent','Mozilla/5.0 (compatible; fpweb)');
  8.     Client.AddHeader('Content-Type','application/HTML; charset=UTF-8');
  9.     Client.AllowRedirect := true;
  10.     Client.ConnectTimeout := 8000;      // mS ?  was 3000, I find initial response from github very slow ....
  11.     Client.IOTimeout := 4000;           // mS ? was 0
  12.     SomeString := '';
  13.     try
  14.         try
  15.             SomeString := Client.Get(URL);
  16.         except
  17.             on E: EHTTPClient do begin                                          // eg, File Not Found, we have asked for an unavailable file
  18.                 ErrorString := 'TMistySync.Downloader - EHTTPClient Error ' + E.Message
  19.                     + ' ResultCode ' + inttostr(Client.ResponseStatusCode);
  20.                 exit(SayDebugSafe(ErrorString));
  21.             end;
  22.             on E: ESocketError do begin
  23.                 ErrorString := 'TMistySync.Downloader - SocketError ' + E.Message     // eg failed dns, timeout etc
  24.                     + ' ResultCode ' + inttostr(Client.ResponseStatusCode);
  25.                 SomeString := 'Fatal, is server available ?';
  26.                 exit(SayDebugSafe(ErrorString));
  27.                 end;
  28.             on E: EInOutError do begin
  29.                 ErrorString := 'TMistySync Downloader - InOutError ' + E.Message;
  30.                 // might generate "TGithubSync Downloader - InOutError Could not initialize OpenSSL library"
  31.                 SomeString := 'Failed to initialise OpenSSL';           // is error message translated ?
  32.                 exit(SayDebugSafe(ErrorString));
  33.                 end;
  34.             on E: ESSL do begin
  35.                 ErrorString := 'TMistySync.Downloader - SSLError ' + E.Message;         // eg openssl problem, maybe FPC cannot work with libopenssl
  36.                 SomeString := 'Failed to work with OpenSSL';
  37.                 exit(SayDebugSafe(ErrorString));
  38.                 end;
  39.             on E: Exception do begin
  40.                 ErrorString := 'TMistySync.Downloader Unexpected Exception ' + E.Message + ' downloading ' + URL;
  41.                 ErrorString := ErrorString + ' HTTPS error no ' + inttostr(Client.ResponseStatusCode);
  42.                 exit(SayDebugSafe(ErrorString));
  43.                 end;
  44.         end;
  45.         Result := Client.ResponseStatusCode = 200;
  46.         // My version of this in GitHubSync then did some processing of Client.ResponseHeaders, apparently not necessary here.
  47.     finally
  48.         Client.Free;
  49.     end;
  50. end;  
           

Davo     
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: How to catch error 400 ?
« Reply #3 on: July 18, 2025, 11:00:23 am »
Thank you for the answers. Yes, I posted it already.
At the moment I am not sure, what to change. Here is my full method.

Be aware it is a work-in-progress-version and has a lot of issues yet.

The first line after try try is it, which drops the error message.
The debugging line below "ShowMessage(Response);" is not seen in case of server-error 400.


Code: Pascal  [Select][+][-]
  1. // sucht zu einem Ticker die Nachrichten
  2. function TNews.Suche_NewsZu(Ticker: string; abDatum, bisDatum: TDate): string;
  3. var URL, Response: string;
  4.     HttpClient: TFPHTTPClient;
  5.     JsonResponse: TJSONData;
  6.     ts_ab, ts_bis: Int64;
  7.     s_from, s_to: string;
  8. begin
  9.   Result := '';
  10.  
  11.   ts_ab := DateTimeToUnix(abDatum);
  12.   ts_bis := DateTimeToUnix(bisDatum + 1);  // period2 ist exklusiv!
  13.  
  14.   s_from := IntToStr(ts_ab);
  15.   s_to := IntToStr(ts_bis);  // brauche ich offenbar nicht, kam von Yahoo-Vorlage
  16.  
  17.   URL := 'https://newsapi.org/v2/everything?q=' + Ticker +
  18.   '&from=' + s_from + '&sortBy=publishedAt&apiKey='+ APIKEY_News;
  19.  
  20.   HttpClient := TFPHTTPClient.Create(nil);
  21.   HttpClient.AddHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36');
  22.   try
  23.     try
  24.       Response := HttpClient.Get(URL);
  25.       ShowMessage(Response);
  26.     except
  27.       on E: EHttpClient do
  28.       begin
  29.         case HttpClient.ResponseStatusCode of
  30.           401: result := 'Unauthorised';
  31.           404: result := 'Not found';
  32.           else
  33.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  34.         end;
  35.       end;
  36.     end;
  37.  
  38.     JsonResponse := GetJSON(Response);
  39.     ShowMessage(JsonResponse);
  40.     Ersetze.JsonWirdDatei(JsonResponse, 'myNews_json');  // ich speichere es einmal ab
  41.     result:=JsonResponse.FormatJSON([]);
  42.  
  43.     result:=VerarbeiteArtikel(result);
  44.   finally
  45.     HttpClient.Free;
  46.   end;
  47. end;
  48.  

dseligo

  • Hero Member
  • *****
  • Posts: 1664
Re: How to catch error 400 ?
« Reply #4 on: July 18, 2025, 12:16:25 pm »
The debugging line below "ShowMessage(Response);" is not seen in case of server-error 400.

Code: Pascal  [Select][+][-]
  1.       on E: EHttpClient do
  2.       begin
  3.         case HttpClient.ResponseStatusCode of
  4.           401: result := 'Unauthorised';
  5.           404: result := 'Not found';
  6.           else
  7.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  8.         end;
  9.       end;
  10.  

In you 'case' code you don't have 400 and in 'else' part code is commented out.

Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: How to catch error 400 ?
« Reply #5 on: July 18, 2025, 03:49:02 pm »
@Dseligo this is what I meant by "work in progress version".
This misses the point, that I see an error message before I have the chance to do anything in the exception block.

In other words:
"try try" does not work as expected.
Therefore I originally did not post the lines which follows "try try". They are not even reached.

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: How to catch error 400 ?
« Reply #6 on: July 18, 2025, 04:07:04 pm »
In other words:
"try try" does not work as expected.
Therefore I originally did not post the lines which follows "try try". They are not even reached.
It does work as expected. Just not what you expected (because you didn't know how exception are handled) ;)

You have this.... the first try matches a finally. So that finally is always executed... as expected...
Code: Pascal  [Select][+][-]
  1. try
  2.     try
  3.       Response := HttpClient.Get(URL);
  4.       ShowMessage(Response);
  5.     except
  6.       on E: EHttpClient do
  7.       begin
  8.         case HttpClient.ResponseStatusCode of
  9.           401: result := 'Unauthorised';
  10.           404: result := 'Not found';
  11.           else
  12.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  13.         end;
  14.       end;
  15.       // JUMPS OUT OF THE COMPLETE PROCEDURE (unless there is an overruling try/finally)
  16.     end;
  17.  
  18.     // THIS ONLY GETS EXECUTED IF NOT EXCEPT
  19.     JsonResponse := GetJSON(Response);
  20.     ShowMessage(JsonResponse);
  21.     Ersetze.JsonWirdDatei(JsonResponse, 'myNews_json');  // ich speichere es einmal ab
  22.     result:=JsonResponse.FormatJSON([]);
  23.  
  24.     result:=VerarbeiteArtikel(result);
  25.   finally
  26.     // EXCEPT JUMPS HERE
  27.     HttpClient.Free;
  28.   end;

But you need to realize that once you get inside an exception part.... everything after that except is not executed. After the except part, the code jumps to the exit (in this case the finally is still executed because that's in a first try overruling).

So if you want a showmessage inside the except... you'll need to put it insude the except or in the finally (I would suggest the except).

The problem is that there is a GetJSON(Response) call before the Showmessage. Does Response contain correct json?
« Last Edit: July 18, 2025, 06:03:13 pm by rvk »

Warfley

  • Hero Member
  • *****
  • Posts: 2038
Re: How to catch error 400 ?
« Reply #7 on: July 18, 2025, 04:15:47 pm »
     [Debuggerausnahmen-Nachricht]
Code: Text  [Select][+][-]
  1. [Break]
  2. Projekt project_xxx hat Exception-Klasse »EHTTPClient« ausgelöst mit der Meldung:
  3. Unexpected response status code: 400
  4.  Bei Adresse 1004B1065
  5. [Diesen Ausnahmetyp übergehen]
  6. [Continue]

What can I do that the error-message is NOT shown to the user but passed on to my except block below?
Thats lazarus, not your program, try running the program without the debugger and see if the same message appears

Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: How to catch error 400 ?
« Reply #8 on: July 18, 2025, 04:24:46 pm »
@rvk
you miss the point, that I do not even get there

@Warfley
This is true! Thank you.
As my software is work in progress I start is usually within the debugger.

Is there an option to say Lazarus, not to drop the error message at this point?
Or a compiler directive for just this line?

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: How to catch error 400 ?
« Reply #9 on: July 18, 2025, 04:27:10 pm »
@rvk
you miss the point, that I do not even get there
You don't get there because there was an exception.
An exception ALWAYS jumps strait out of the routine directly after the except clause is done.

Your Showmessage is below that except begin/end so never gets executed when there is an exception.

Please read the commented and highlighted lines in my example.

See below...
« Last Edit: July 18, 2025, 06:01:39 pm by rvk »

af0815

  • Hero Member
  • *****
  • Posts: 1409
Re: How to catch error 400 ?
« Reply #10 on: July 18, 2025, 05:52:09 pm »
Is there an option to say Lazarus, not to drop the error message at this point?
Maybe go into "Options for Project xx" there in Project options, Language Exceptions and enter there "EHTTPClient". But this suppress all stops from this exception.
regards
Andreas

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: How to catch error 400 ?
« Reply #11 on: July 18, 2025, 06:00:05 pm »
Oops. I was wrong. It will execute after except.
Code: Pascal  [Select][+][-]
  1. begin
  2.   try
  3.     try
  4.       raise Exception.Create('a');
  5.       Showmessage('a');
  6.     except
  7.       Showmessage('b');
  8.     end;
  9.     Showmessage('c'); // will execute on except
  10.   finally
  11.     Showmessage('d');
  12.   end;
  13. end;

So the showmessage should have been shown.
BUT... you have a line JsonResponse := GetJSON(Response); just above that ShowMessage.
What does Response contain???? Does it contain correct json after a code 400?


Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: How to catch error 400 ?
« Reply #12 on: July 21, 2025, 11:18:01 am »
@rvk
thank you for your answer.
However, I do not understand it.

Please be aware, that I do not work much with servers and usually not with exceptions They "never" fix what I want to fix.

So dummy question: Where shall I write the url-get line, which drops the exception? (fulll code posting above)

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: How to catch error 400 ?
« Reply #13 on: July 21, 2025, 11:59:06 am »
So dummy question: Where shall I write the url-get line, which drops the exception? (fulll code posting above)
Consider this (your) code:

Code: Pascal  [Select][+][-]
  1.     try
  2.       Response := HttpClient.Get(URL);
  3.       ShowMessage(Response);
  4.     except
  5.       on E: EHttpClient do
  6.       begin
  7.         case HttpClient.ResponseStatusCode of
  8.           401: result := 'Unauthorised';
  9.           404: result := 'Not found';
  10.           else
  11.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  12.         end;
  13.       end;
  14.     end;
  15.  
  16.     // WHAT IS THE VALUE OF RESPONSE HERE ????
  17.     JsonResponse := GetJSON(Response);
  18.     ShowMessage(JsonResponse);
  19.     Ersetze.JsonWirdDatei(JsonResponse, 'myNews_json');  // ich speichere es einmal ab
  20.     result:=JsonResponse.FormatJSON([]);
What is the value of Response on lines 16/17 (highlighted)???
Because you get an exception in line 2, you can't be sure of what the content of Response is !!!

In line 17 you have a line GetJSON(Response). But are you sure Response contains "correct" json ???
I'm sure it doesn't... so you probably get a second exception.

One options is that you can move the handling of a correct Response inside the try.
Like this:
Code: Pascal  [Select][+][-]
  1.     try
  2.       Response := HttpClient.Get(URL);
  3.       JsonResponse := GetJSON(Response);
  4.       ShowMessage(JsonResponse);
  5.       Ersetze.JsonWirdDatei(JsonResponse, 'myNews_json');  // ich speichere es einmal ab
  6.       result:=JsonResponse.FormatJSON([]);
  7.       result:=VerarbeiteArtikel(result);
  8.     except
  9.       on E: EHttpClient do
  10.       begin
  11.         case HttpClient.ResponseStatusCode of
  12.           401: result := 'Unauthorised';
  13.           404: result := 'Not found';
  14.           else
  15.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  16.         end;
  17.       end;
  18.     end;

Another option is to only process the Response if result isn't filled in by the case in the except.
Like this:
Code: Pascal  [Select][+][-]
  1.     try
  2.       Response := HttpClient.Get(URL);
  3.       ShowMessage(Response);
  4.     except
  5.       on E: EHttpClient do
  6.       begin
  7.         case HttpClient.ResponseStatusCode of
  8.           401: result := 'Unauthorised';
  9.           404: result := 'Not found';
  10.           else
  11.           //  result := Format('error: %d', [HttpClient.ResponseStatusCode]);
  12.         end;
  13.       end;
  14.     end;
  15.  
  16.     if result = '' then // no errors found
  17.     begin
  18.       JsonResponse := GetJSON(Response);
  19.       ShowMessage(JsonResponse);
  20.       Ersetze.JsonWirdDatei(JsonResponse, 'myNews_json');  // ich speichere es einmal ab
  21.       result:=JsonResponse.FormatJSON([]);
  22.       result:=VerarbeiteArtikel(result);
  23.     end;

At least that way... the Response only gets processed when there is no error on the page (401 or 404).

Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: How to catch error 400 ?
« Reply #14 on: July 21, 2025, 02:54:42 pm »
Thank you for trying.
Unfortunately all this is too late:

"Response := HttpClient.Get(URL);"
triggers the exception although written after the try.

This is due to the Lazarus debugger, not to the compiled software.
As I usually run my software from the debugger, I keep clicking away error messages.
In this very case every time I search for a unknown word, which has no entry on a site, it is triggered. Annoying.

in other words:
The answer of AF (above, very small paragraph) may be a workaround. I am not sure, if I want to try it, because I do not understand what this may mean to my debugging.

 

TinyPortal © 2005-2018