본문 바로가기
앱 프로그래밍/flutter

플러터로 기상청 날씨 앱 만들기 일지 5. 기상청 API 데이터 연동 오류 수정(HTTP service에러는 해결 불가능...)

by 청량리 물냉면 2022. 1. 14.
반응형

API 에러

00 NORMAL_SERVICE 정상
01 APPLICATION_ERROR 어플리케이션 에러
02 DB_ERROR 데이터베이스 에러
03 NODATA_ERROR 데이터없음 에러
04 HTTP_ERROR HTTP 에러
05 SERVICETIME_OUT 서비스 연결실패 에러
10 INVALID_REQUEST_PARAMETER_ERROR 잘못된 요청 파라메터 에러
11 NO_MANDATORY_REQUEST_PARAMETERS_ERROR 필수요청 파라메터가 없음
12 NO_OPENAPI_SERVICE_ERROR 해당 오픈API서비스가 없거나 폐기됨
20 SERVICE_ACCESS_DENIED_ERROR 서비스 접근거부
21 TEMPORARILY_DISABLE_THE_SERVICEKEY_ERROR 일시적으로 사용할 수 없는 서비스 키
22 LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS_ERROR 서비스 요청제한횟수 초과에러
30 SERVICE_KEY_IS_NOT_REGISTERED_ERROR 등록되지 않은 서비스키
31 DEADLINE_HAS_EXPIRED_ERROR 기한만료된 서비스키
32 UNREGISTERED_IP_ERROR 등록되지 않은 IP
33 UNSIGNED_CALL_ERROR 서명되지 않은 호출
99 UNKNOWN_ERROR 기타에러

 

경험상 가장 많이 등장하는 에러는 04 HTTP_ERROR01 APPLICATION_ERROR

HTTP_ERROR는 기상청 서버에서 정보를 받아오지 못해 생기는 에러로 개발자가 할 수 있는 조치는 거의 없다. 

APPLICATION_ERROR는 base_time이나 base_date를 잘못 입력했을 때 발생했다. (00시에 당일의 데이터를 요청한다던지... ☞기상청 단기예보는 0200시에 업데이트 되므로 0시 ~ 1시까지는 전날 2300시 데이터를 불러와야 한다.)

 

 

+ HTTP_ERROR와 APPLICATION_ERROR 문의에 대한 공공데이터 포털 답변 (출처: https://www.data.go.kr/bbs/qna/selectQnaList.do)

 

HTTP_ERROR

* 안녕하세요.. 공공데이터 활용지원센터입니다.

먼저 이용에 불편드린점 양해부탁 드립니다.

HTTP ERROR는 제공기관으로부터 잘못된 결과를 받았을 경우 공공데이터포털에서 출력되는 메세지로
제공기관의 endPoint의 서버 응답이 없을 경우나 연계 오류가 있을 경우등에 발생됩니다.
지원센터에서 확인한 바로 연계상에 문제가 없으며,  일시적인 오류가 있었을 것으로 보입니다.

API를 사용하지 못하는 시간은 장애로 인한 시스템 점검등이 있을 경우이나
해당 API와 관련하여 점검이 진행된 것은 없습니다.

API이용에 불편을 드려 죄송합니다.

감사합니다.

 

APPLICATION_ERROR

** 안녕하세요 공공데이터활용지원센터입니다.
먼저 이용에 불편드린점 양해부탁드립니다. 
"APPLICATION ERROR" 오류는 필수파라미터(요청변수) 미입력시 보여지는 오류이며, 활용가이드 참고하시어 호출해 주시기 바랍니다. 호출하셨던 URL 주소(인증키 포함) 비공개로 남겨주시면 추가 확인후 답변드리도록 하겠습니다. 감사합니다.

 

 

내가 APPLICATION_ERROR를 해결한 방법

base time과 base date 값이 제대로 출력되고 있는지 확인했다. ☞시간별 분기에서 예외가 발생하여, 해당 부분 개선

 

 

base_time과 base_date 설정하는 코드 개선

if ((now.hour == 1 && now.minute >= 41) || (now.hour == 2 && now.minute <= 40)){ //1시 41분 ~ 2시 40분 예보
      return "0100";
    } else if ((now.hour == 2 && now.minute >= 41) || (now.hour == 3 && now.minute <= 40)){ //2시 41분 ~ 3시 40분 예보
      return  "0200";
    } else if ((now.hour == 3 && now.minute >= 41) || (now.hour == 4 && now.minute <= 40)){
      return  "0300";
    } else if ((now.hour == 4 && now.minute >= 41) || (now.hour == 5 && now.minute <= 40)){
      return  "0400";
    } else if ((now.hour == 5 && now.minute >= 41) || (now.hour == 6 && now.minute <= 40)){
      return  "0500";
    } else if ((now.hour == 6 && now.minute >= 41) || (now.hour == 7 && now.minute <= 40)){
      return  "0600";
    } else if ((now.hour == 7 && now.minute >= 41) || (now.hour == 8 && now.minute <= 40)){
      return  "0700";
    } else if ((now.hour == 8 && now.minute >= 41) || (now.hour == 9 && now.minute <= 40)){
      return  "0800";
    } else if ((now.hour == 9 && now.minute >= 41) || (now.hour == 10 && now.minute <= 40)){
      return  "0900";
    } else if ((now.hour == 10 && now.minute >= 41) || (now.hour == 11 && now.minute <= 40)){
      return  "1000";
    } else if ((now.hour == 11 && now.minute >= 41) || (now.hour == 12 && now.minute <= 40)){
      return  "1100";
    } else if ((now.hour == 12 && now.minute >= 41) || (now.hour == 13 && now.minute <= 40)){
      return  "1200";
    } else if ((now.hour == 13 && now.minute >= 41) || (now.hour == 14 && now.minute <= 40)){
      return  "1300";
    } else if ((now.hour == 14 && now.minute >= 41) || (now.hour == 15 && now.minute <= 40)){
      return  "1400";
    } else if ((now.hour == 15 && now.minute >= 41) || (now.hour == 16 && now.minute <= 40)){
      return  "1500";
    } else if ((now.hour == 16 && now.minute >= 41) || (now.hour == 17 && now.minute <= 40)){
      return  "1600";
    } else if ((now.hour == 17 && now.minute >= 41) || (now.hour == 18 && now.minute <= 40)){
      return  "1700";
    } else if ((now.hour == 18 && now.minute >= 41) || (now.hour == 19 && now.minute <= 40)){
      return  "1800";
    } else if ((now.hour == 19 && now.minute >= 41) || (now.hour == 20 && now.minute <= 40)){
      return  "1900";
    } else if ((now.hour == 20 && now.minute >= 41) || (now.hour == 21 && now.minute <= 40)){
      return  "2000";
    } else if ((now.hour == 21 && now.minute >= 41) || (now.hour == 22 && now.minute <= 40)){
      return "2100";
    } else if ((now.hour == 22 && now.minute >= 41) || (now.hour == 23 && now.minute <= 40)){
      return "2200";
    } else if ((now.hour == 23 && now.minute >= 41) || (now.hour == 0 && now.minute <= 40)){
      return "2300";
    } else if ((now.hour == 0 && now.minute >= 41) || (now.hour == 1 && now.minute <= 40)) {
      return "0000";
    }

 

위의 코드를

//40분 이전이면 현재 시보다 1시간 전 base_time 요청
if (now.minute <= 40){
  // 00:40분 이전이라면 base_date는 전날이고 base_time은 2300이다.
  if (now.hour == 0) {
    currentBaseDate = DateFormat('yyyyMMdd').format(now.subtract(Duration(days:1)));
    currentBaseTime = '2300';
  } else {
    currentBaseDate = DateFormat('yyyyMMdd').format(now);
    currentBaseTime = DateFormat('HH00').format(now.subtract(Duration(hours:1)));
  }
}
//40분 이후면 현재 시와 같은 base_time을 요청
else{
  currentBaseDate = DateFormat('yyyyMMdd').format(now);
  currentBaseTime = DateFormat('HH00').format(now);
}

이렇게 고쳤다. 훨씬 간결하고 00시에 새로운 날짜의 데이터가 생성되지 않아 받아오지 못했던 문제를 해결했다.

 

 

참고한 블로그: https://glow153.tistory.com/12

 

[Java] 공공데이터포털 Open API 사용하기 - 동네예보 (2)

지난시간에 이어서 공공데이터포털 Open API를 사용하여 특정 지역의 날씨를 얻어오는 방법을 알아보자. 동네예보조회서비스는 xml과 json 형태로 날씨예보 데이터를 제공한다. 이 데이터 내용을

glow153.tistory.com

 

 

초단기 예보의 base_time과 base_date구하는 공식도 동일한 방식으로 고쳐주었다.

//45분 이전이면 현재 시보다 1시간 전 base_time 요청
  if (now.minute <= 45){
    //00:45분 이전이라면 base_date는 전날이고 base_time은 2330
    if (now.hour == 0) {
      sswBaseDate = DateFormat('yyyyMMdd').format(now.subtract(Duration(days:1)));
      sswBaseTime = '2330';
    } else {
      sswBaseDate = DateFormat('yyyyMMdd').format(now);
      sswBaseTime = DateFormat('HH30').format(now.subtract(Duration(hours:1)));
    }
  }
  //45분 이후면 현재 시와 같은 base_time을 요청
  else{ //if (now.minute > 45)
    sswBaseDate = DateFormat('yyyyMMdd').format(now);
    sswBaseTime = DateFormat('HH30').format(now);
  }
  
//아래는 기존의 코드  
//   if ((now.hour == 1 && now.minute >= 46) || (now.hour == 2 && now.minute <= 45)){ //1시 41분 ~ 2시 40분 예보
//     return "0130";
//   } else if ((now.hour == 2 && now.minute >= 46) || (now.hour == 3 && now.minute <= 45)){ //2시 ~ 3시 40분 예보
//     return "0230";
//   } else if ((now.hour == 3 && now.minute >= 46) || (now.hour == 4 && now.minute <= 45)){
//     return "0330";
//   } else if ((now.hour == 4 && now.minute >= 46) || (now.hour == 5 && now.minute <= 45)){
//     return "0430";
//   } else if ((now.hour == 5 && now.minute >= 46) || (now.hour == 6 && now.minute <= 45)){
//     return "0530";
//   } else if ((now.hour == 6 && now.minute >= 46) || (now.hour == 7 && now.minute <= 45)){
//     return "0630";
//   } else if ((now.hour == 7 && now.minute >= 46) || (now.hour == 8 && now.minute <= 45)){
//     return "0730";
//   } else if ((now.hour == 8 && now.minute >= 46) || (now.hour == 9 && now.minute <= 45)){
//     return "0830";
//   } else if ((now.hour == 9 && now.minute >= 46) || (now.hour == 10 && now.minute <= 45)){
//     return "0930";
//   } else if ((now.hour == 10 && now.minute >= 46) || (now.hour == 11 && now.minute <= 45)){
//     return "1030";
//   } else if ((now.hour == 11 && now.minute >= 46) || (now.hour == 12 && now.minute <= 45)){
//     return "1130";
//   } else if ((now.hour == 12 && now.minute >= 46) || (now.hour == 13 && now.minute <= 45)){
//     return "1230";
//   } else if ((now.hour == 13 && now.minute >= 46) || (now.hour == 14 && now.minute <= 45)){
//     return "1330";
//   } else if ((now.hour == 14 && now.minute >= 46) || (now.hour == 15 && now.minute <= 45)){
//     return "1430";
//   } else if ((now.hour == 15 && now.minute >= 46) || (now.hour == 16 && now.minute <= 45)){
//     return "1530";
//   } else if ((now.hour == 16 && now.minute >= 46) || (now.hour == 17 && now.minute <= 45)){
//     return "1630";
//   } else if ((now.hour == 17 && now.minute >= 46) || (now.hour == 18 && now.minute <= 45)){
//     return "1730";
//   } else if ((now.hour == 18 && now.minute >= 46) || (now.hour == 19 && now.minute <= 45)){
//     return "1830";
//   } else if ((now.hour == 19 && now.minute >= 46) || (now.hour == 20 && now.minute <= 45)){
//     return "1930";
//   } else if ((now.hour == 20 && now.minute >= 46) || (now.hour == 21 && now.minute <= 45)){
//     return "2030";
//   } else if ((now.hour == 21 && now.minute >= 46) || (now.hour == 22 && now.minute <= 45)){
//     return "2130";
//   } else if ((now.hour == 22 && now.minute >= 46) || (now.hour == 23 && now.minute <= 45)){
//     return "2230";
//   } else if ((now.hour == 23 && now.minute >= 46) || (now.hour == 0 && now.minute <= 45)){
//     return "2330";
//   } else if ((now.hour == 0 && now.minute >= 46) || (now.hour == 1 && now.minute <= 45)) {
//     return "0030";
//   }
 }
반응형