C/400

42. API エラー報告

API を使用するときにも API のエラーのモニター処理をしていないとそのまま、あたかもエラーが
起こらなかったのかのように処理を進めていくと予測できない結果を生じる。
またエラーの発見が困難になってしまうのでAPI の実行にも、必ずエラー処理を行うようにして
おきたいものである。
API のエラー・コードはシステムAPI 解説書に説明されているが説明が適切でない部分があるため、
ユーザーにとってややわかりにくいものとなっている。
ここでは、その意味と使用方法を解説する。

さて、API のエラー・コードはすべて統一されていて次の形式をしている。

開始位置使用タイプ項目の説明
1入力BIN(4)エラー・コード全体の長さ (=116)
5出力BIN(4)API から戻された長さ
9出力CHR(7)エラー・メッセージ ID (MSGID)
16出力CHR(1)予約済み(未使用)
17出力CHR(100)メッセージ・データ (MSGDTA)
【 解説 】

エラーがなくAPI が正常に終了した場合には、「API から戻された長さ」は 0 であり、
「API から戻された長さ」が 0 でない場合は、エラーが発生したものと判別することができる。
次にエラーが発生したとすると「エラー・メッセージ ID 」には QCPFMSG のメッセージ識別コード(MSGID) が戻る。
そして「メッセージ・データ」が、このエラー・メッセージに対するメッセージ・データとして戻る
のである。
このことが IBM システムAPI 解説書 には明記されていないため、読み手が理解しにくい
状況になっているのと同時に APIエラー処理の例がほとんどない。
以上のことを理解した上で次のサンプルC/400ソースを参照して頂きたい。

【 サンブルC/400 】
#include <stdio.h>                                                    
#include <stdlib.h>                                                   
#include <string.h>                                                   
#include <QUSCRTUS.h>                                                 
#include <QMHRTVM.h>                                                  
                                                                      
#define TRUE         0                                                
#define FALSE       -1                                                
typedef struct {                                                      
   int  BYTESPRO;                                                     
   int  BYTESAVL;                                                     
   char MSGID[7];                                                     
   char RESRVD;                                                       
   char EXCPDATA[100];                                                
} ERRSTRUCTURE;     /* Define the error return structure            */
ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */      
                                                                      
void main(void){                                                      
  char msgid[8], msgdta[100];                                         
  int  msglen, msgdtalen, pos;                                        
  char* Message;                                                   
  char* ptr;                                                       
  typedef struct {                                                 
    Qmh_Rtvm_RTVM0100_t  rtvm0100;                                 
    char msg[512];                                                 
  } ERRMSG;                                                        
  ERRMSG errmsg;                                                   
                                                                   
  errcode.BYTESPRO = 160;                                          
  errcode.BYTESAVL  = 0;                                           
  QUSCRTUS("MYSPACE   ATEMP     ", "PF        ", 1000, " ",        
                 "*ALL      ", "INZLIB ユーザー空間 ",             
                 "*YES      ", &errcode);                          
  if(errcode.BYTESAVL != 0){/* APIERR */                           
    memset(msgid, 0, sizeof(msgid));                               
    memcpy(msgid, errcode.MSGID, 7);                               
    msgid[7] = 0x00;                                               
    memset(msgdta, 0, sizeof(msgdta));                             
    memcpy(msgdta, errcode.EXCPDATA, 100);                         
    msglen = sizeof(ERRMSG);                                       
    msgdtalen = strlen(msgdta);                                    
    memset(&errmsg, 0, sizeof(ERRMSG));                             
    QMHRTVM(&errmsg,  msglen, "RTVM0100", msgid, "QCPFMSG   *LIBL   
          msgdta, msgdtalen, "*YES      ", "*YES      ", &errcode); 
    printf("ERROR = %sn", errmsg.msg);                             
    getchar();                                                      
  }/* APIERR */                                                     
}
【 解説 】

この API : QUSCRTUS によるユーザー・スペースの作成はライブラリー名を ATEMP という
名前にして意図的にエラーが発生するようにしている。
API エラー・コードの構造に合わせて MSGID と MSGDTA を取り出して API: QMHRTVM
を使ってメッセージに組み立てて、printf で出力している。