Getting HTTPAPI error information

Discussions related to HTTPAPI (An HTTP Client Package for RPG programming.) http://www.scottklement.com/httpapi/
Post Reply
JJDalglish
Posts: 4
Joined: Wed Oct 06, 2021 10:32 pm

Getting HTTPAPI error information

Post by JJDalglish »

Hello,
This is my very first attempt at using http inside RPGLE to interface with outside apps and I first want to THANK YOU a ton for having provided the http_string proc! I have only learned a little so far, but I have learned enough to see what you have provided will save me an immense amount of time and effort!

I created a small program to learn the process and prove to myself it works. The program sends out a simple request to create a new department. If the department is created, a success response if given and all is ok. If it is not created (say because it already exists), the request fails and JSON information is sent back saying so.

When I use the program to create a NEW department, everything works fine, so I know the programming and process is correct and does indeed work.

However, when purposely trying to force an error by creating a pre-existing department (so I can see the error information being returned), the http_response field ends up being empty!

I did try using http_error to see if the error information I need could be found there, but I am not seeing that it returns any particularly useful information (such as “department already exits”).

I have included the program source and resulting log information.

Ideally all I need in the error response is the JSON shown in the end of the log (3rd line up from bottom). But if that is too specific, I would be happy in getting all of the error information back because I could easily pick out just the parts I need.

Is there a way the program can get much more information when an “error” occurs?

Thank you!

Here is the program source:

Code: Select all

       
       Ctl-Opt bnddir( 'LIBHTTP/HTTPAPI' );
       Ctl-Opt option( *srcstmt : *nodebugIO );

       /include libhttp/qrpglesrc,httpapi_h

       Dcl-S  http_response     Varchar(3000);
       Dcl-S  errorMsg          char(300);
       Dcl-S  xErrorNo          int(10);
       Dcl-S  xRespCode         int(10);

       //------------------------------------------------------------------------------------

       // Turn on HTTPAPI debug
          http_debug(*on : '/Home/http_debug_log.txt' ) ;


       //------------------------------------------------------------------------------------

          // First add the additional headers needed for the POST request
          http_xproc( HTTP_POINT_ADDL_HEADER : %paddr(addSpecialHeaders) );


          // Perform POST operation to add the new department
          // Note:  Dept ID 771 already exists, it is being added
          //        here in order to force a "duplicate dept" error.
          Monitor;
             http_response = HTTP_string(
                      'POST' :
                      'https://my-test.testapi.com/department/create':
                      '{"id":"771","name":"Test Dept 771"}':
                      'application/json');

          // ----------- ERROR! -----------
          On-error;
             errorMsg = http_error( xErrorNo : xRespCode );
             http_comp('Error!     xErrorNo: '  + %char(xErrorNo) +
                               '   xRespCode: ' + %char(xRespCode) +
                               '   errorMsg:  ' + errorMsg );
          EndMon;


       *InLr = *On;
       Return;

       //****************************************************************************************
       //****************************************************************************************

       Dcl-Proc addSpecialHeaders;
         Dcl-Pi *N;
            headersToAdd    Varchar(32767);
         End-Pi;

         Dcl-c  CRLF  x'0d25';

         headersToAdd = 'X-API-Key: wQ4pihmtn42pqP' + CRLF
                        + 'Return-Request: 0' + CRLF
                        + 'Return-Response: 0' + CRLF;

       End-Proc; 

Here is the resulting log:

Code: Select all

 
 ************Beginning of data**************
HTTPAPI Ver 1.45 released 2021-09-20
NTLM Ver 1.4.0 released 2014-12-22
OS/400 Ver V7R3M0

http_persist_open(): entered
http_long_ParseURL(): entered
DNS resolver retrans: 2
DNS resolver retry  : 2
DNS resolver options: x'00000136'
DNS default domain: MYDOMAIN.COM
DNS server found: 10.10.10.10
DNS server found: 10.10.10.12
DNS server found: 10.9.10.10
Nagle's algorithm (TCP_NODELAY) disabled.
SNI hostname set to: my-test.testapi.com

Serial Number: 7F:75:0E:05:25:D4:E2:6E:F0:7D:29:2D:16:12:6D:1A
Common Name: *.testapi.com
Common Name: *.testapi.com
Issuer CN: Sectigo RSA Domain Validation Secure Server CA
Issuer Country: GB
Issuer State/Province: Greater Manchester
Issuer Locality: Salford
Issuer Org: Sectigo Limited
Version: 3
not before: 20201110180000
Unknown Field: 18:00:00 10-11-2020
not after: 20211204175959
Unknown Field: 17:59:59 04-12-2021
pub key alg: 1.2.840.113549.1.1.1
signature algorithm: 1.2.840.113549.1.1.11
Unknown Field: 0382010F003082010A0282010100B1E361EBD4DD0F194E4B1AF7436FF7A9260E4EB8FDE4B2C89970B21B570D21F41F3925F7D55E38FD6D600E83E
Unknown Field: 2048
Unknown Field: 2369428A91368548500536CA9E4A7DFD
Unknown Field: 1.2.840.113549.2.5
Unknown Field: 9C5B03B74A1093C3212E07E391C24EFC531AD0F0
Unknown Field: 116482F3E72A75CACE7DFBE54F3EF792702F2AE8814747BFA72C31E6A242341C
Unknown Field: 116482F3E72A75CACE7DFBE54F3EF792702F2AE8814747BFA72C31E6A242341C
Unknown Field: 5
Unknown Field: *.testapi.com
Unknown Field: 0
Unknown Field: 1.3.6.1.5.5.7.3.2
Unknown Field: 1.3.6.1.5.5.7.3.1
Unknown Field: 2.23.140.1.2.1
Unknown Field: 1.3.6.1.4.1.6449.1.2.2.7
Unknown Field: http://ocsp.sectigo.com

Protocol Used: TLS Version 1.2
http_persist_req(POST) entered.
http_long_ParseURL(): entered
http_long_ParseURL(): entered
do_oper(POST): entered
There are 0 cookies in the cache
POST /department/create HTTP/1.1
Host: my-test.testapi.com
User-Agent: http-api/1.45
User-Agent: http-api/1.45
Content-Type: application/json
Content-Length: 35
X-API-Key: wQ4pihmtn42pqP
Return-Request: 0
Return-Response: 0


senddoc(): entered
{"id":"771","name":"Test Dept 771"}
recvresp(): entered
HTTP/1.1 400 Bad Request
Date: Tue, 12 Oct 2021 22:57:03 GMT
Content-Type: application/json
Content-Length: 615
Connection: keep-alive
x-amzn-RequestId: 693ca768-fa82-4adc-bf59-d02a26bcd524
Access-Control-Allow-Origin: *
x-amz-apigw-id: HHfdyEe4IAMFjJQ=
x-amz-apigw-id: HHfdyEe4IAMFjJQ=
X-Amzn-Trace-Id: Root=1-616612be-5e35ae2b2c9829163fdd862a;Sampled=0


SetError() #13: HTTP/1.1 400 Bad Request
recvresp(): end with 400
recvdoc parms: identity 615
header_load_cookies() entered
recvdoc(): entered
SetError() #0:
recvdoc(): Receiving 145 bytes.
{"statusCode":400, "errorCode":"E002438", "errorMessage":"Request failed", "errorno":"BL34000061", "description":"Department 771 already exists"}
SetError() #13: HTTP/1.1 400 Bad Request
http_close(): entered
 ************End of Data******************** 
Scott Klement
Site Admin
Posts: 872
Joined: Sun Jul 04, 2021 5:12 am

Re: Getting HTTPAPI error information

Post by Scott Klement »

Hi there,

http_string() is meant as a way to make it easy to code -- but, it does make some assumptions that may not be right for you. One of its assumptions is that any response code aside from 200=Success means that it should send an *escape message.

But, perhaps in your case, you don't want an escape message? Perhaps you would treat a 400 response as a non-fatal error to make it easier to get back the http_response variable and look for a message inside of it? In that case, you would want to use http_req() instead of the http_string() shortcut. You would code it as follows:

Code: Select all

         //Monitor;
         //    http_response = HTTP_string(
         //             'POST' :
         //             'https://my-test.testapi.com/department/create':
         //             '{"id":"771","name":"Test Dept 771"}':
         //             'application/json');
         //
         // // ----------- ERROR! -----------
         // On-error;
         //    errorMsg = http_error( xErrorNo : xRespCode );
         //    http_comp('Error!     xErrorNo: '  + %char(xErrorNo) +
         //                      '   xRespCode: ' + %char(xRespCode) +
         //                      '   errorMsg:  ' + errorMsg );
         // EndMon;

          if HTTP_req( 'POST'
                     : 'https://my-test.testapi.com/department/create'
                     : *omit
                     : http_response
                     : *omit
                     : '{"id":"771","name":"Test Dept 771"}'
                     : 'application/json') <> 1;
              errorMsg = http_error( xErrorNo : xRespCode );
              http_comp('Error!     xErrorNo: '  + %char(xErrorNo) +
                                '   xRespCode: ' + %char(xRespCode) +
                                '   errorMsg:  ' + errorMsg );
          endif;
Then, you could interpret the http_response (possibly using DATA-INTO) to get back the 'description' from the JSON document that says "Department 771 already exists".

Just a thought.
JJDalglish
Posts: 4
Joined: Wed Oct 06, 2021 10:32 pm

Re: Getting HTTPAPI error information

Post by JJDalglish »

PERFECT!!!! Exactly what I needed!

THANK YOU so much for your help and for creating the HTTPAPI package!
Post Reply