'코딩'에 해당되는 글 13

  1. 2010.12.10 BigDecimal - 100 과 100.00
  2. 2010.10.07 황당한 실수
  3. 2010.05.23 파일 경로
  4. 2010.04.13 허무함. 뭐가 잘못된 걸까?
  5. 2009.12.18 잘못된 예외 처리로 인해 엉뚱한 에러 발생
  6. 2009.10.22 예외 추적
  7. 2009.04.29 JDBC Code Template
  8. 2009.04.23 해서는 안되는 예외 처리 - 아무것도 안하는 경우
  9. 2009.04.18 좋은 코딩 습관 - 리턴값 확인
  10. 2009.04.18 좋은 코딩 습관 - 상태 기준을 엄격하게 잡기
  11. 2009.04.02 Javascrpt 개체 접근하기
  12. 2009.02.22 java.math.BigDecimal
  13. 2009.02.13 Eclipse Code Assist

BigDecimal - 100 과 100.00

합이 100인지 비교하는 코드가 있다.
합이 100.00인데 예외가 발생한다. 테스트케이스를 작성해 본다.
BigDecimal#equals() 는 scale을 비교한다.

데이터베이스에서 데이터를 가져와서 비교할때 primitive type으로 비교하는게 좋을거 같다.

황당한 실수

이클립스에서 경고해 준다.

파일 경로

어떤 개발자가 이런 점을 이용해서 유닉스 환경과 로컬 개발 환경을 구성해서 사용하더라.

허무함. 뭐가 잘못된 걸까?

화면에서 데이터를뿌려주는데 아무리해도 OK가 나오지 않는다.
개발자가 1시간동안 헤맷다고 한다.

잘못된 예외 처리로 인해 엉뚱한 에러 발생

데이터 형식 nvarchar을(를) numeric(으)로 변환하는 중 오류가 발생했습니다.

갑자기 에러가 발생했다.
이런 에러가 예전부터 많이 나오긴 했었다.

문제가 없는 쿼리인데 에러가 발생한다.

로그를 보니 이상한 로그가 있다.
DEXTUploadException --> 데이터를 읽어오는 데 실패했습니다. 사용자와의 연결이 끊어졌거나 업로드를 중지했습니다.

예외를 잡아서 로그만 남기고 아무런 처리를 하지 않는다.
업로드컴포넌트에서 처리가 되지 않아서 DAO에서 쿼리문을 처리할때 pk2가 빈 문자열이 넘어온거 같다.
(웹요청에 대한 값을 Map에 넣었다가 getString(NAME) 같은 메서드로 처리하는데 NAME으로 된 값이 없으면 빈 문자열로 처리하게 되어 있음)

결국에는 아래와 같은 쿼리가 실행되었다.

업로드컴포넌트에서 에러가 난 이유는 디스크가 다 차서 더이상 용량이 남아 있지 않았다고 한다.

- 2010-02-08
다른 프로그램에서 동일한 에러 발생
전송을 했는데 화면이 정지하고 반응이 없었다고 함.
서버/네트워크 사용량이 많아서인지, 업체 PC 사양이 떨어져서 그런지는 불분명함.

예외 추적

10-15 15:13:43 ERROR com.xxx.client.connect.transmit.SendSOAPServiceImpl.proc(SendSOAPServiceImpl.java:343) - com.xxx.client.connect.transmit.SOAPException
10-15 15:13:43 ERROR com.xxx.client.connect.transmit.SendSOAPServiceImpl.proc(SendSOAPServiceImpl.java:344) -
10-15 15:13:43 INFO com.xxx.client.connect.transmit.SendServlet.doPost(SendServlet.java:89) - +++++++++++++++++++++null

예외가 어디서 발생했는지 로그에 쓸만한 정보가 없다.
로그를 기록하는 부분을 다음과 같이 변경한다.
10-22 09:19:59 ERROR com.xxx.client.connect.transmit.SendSOAPServiceImpl.proc(SendSOAPServiceImpl.java:343) - com.xxx.client.connect.transmit.SOAPException
10-22 09:19:59 ERROR com.xxx.client.connect.transmit.SendSOAPServiceImpl.proc(SendSOAPServiceImpl.java:344) -
10-22 09:20:00 ERROR com.xxx.client.connect.transmit.SendServlet.doPost(SendServlet.java:90) - error
com.xxx.client.connect.transmit.SOAPException
    at com.xxx.client.connect.transmit.ApplicationXMLHandler.validate(ApplicationXMLHandler.java:862)
    at com.xxx.client.connect.transmit.ApplicationXMLHandler$$FastClassByCGLIB$$3ea56c40.invoke(<generated>)
    ...
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:534)
Caused by: java.security.NoSuchAlgorithmException
    at signgate.crypto.util.MDUtil.<init>(MDUtil.java:127)
    at com.xxx.client.connect.transmit.ApplicationXMLHandler.validate(ApplicationXMLHandler.java:849)
    ... 55 more

JDBC Code Template


PreparedStatement ps = null;
try{
    ps = con.prepareStatement(QUERY);
    int idx = 0;
    ps.setString(++idx, COL_1);
    ...
    ps.setString(++idx, COL_N);
    
    return ps.executeUpdate();

}catch(Exception e){
    throw new RuntimeSQLException(e, primaryKey);
}finally{
    if(ps != null){ try{ ps.close(); }catch(Exception ignored){  }
}
Connection con = null;
PrepareStatement ps = null;

try{
	ps = con.prepareStatement(QUERY);  
	int idx = 0;  
	ps.setString(++idx, COL_1);  
	...  
	ps.setString(++idx, COL_N);  

	int affectedRow = ps.executeUpdate();
	if(affectedRow != 1){
		throw new RuntimeSQLException(" expected : 1, result : " + affectedRow
			, primaryKey); //=-=> 정형화...
	}
	con.commit();
}catch(Exception e){
	con.rollback();
	throw new RuntimeSQLException(e, primaryKey);
}finally{
    if(ps != null){ try{ ps.close(); }catch(Exception ignored){  }
    if(con != null){ try{ con.close(); }catch(Exception ignored){  }
}

해서는 안되는 예외 처리 - 아무것도 안하는 경우

예외를 잡아서 아무것도 처리하지 않는 경우 예외가 발생했는지도 모르기 때문에 유지보수가 힘들다.
필요한 경우가 아닌 경우 절대 해서는 안되는 방식이다.
로그만 남기고 지나는 경우도 별반 다르지 않다.
사용자는 예외가 발생했는지 인지할수가 없다.
그냥 안된다고만 한다.
예외처리를 하더라도 로그는 남겨야 한다.(로그는 중앙집중적으로 한곳에서 남겨야 한다.)
에러났다고 하는데 원인을 파악할 수 없다.
  [todo] 적절한 예외 처리 를 정리할 것.

좋은 코딩 습관 - 리턴값 확인

자바는 예외로 처리할 수 있지만 C 언어같은 경우는 실행성공유무를 리턴값으로 돌려 준다.
이런 리턴값을 확인하지 않고 넘어가는 경우 디버깅하기가 힘들다.

SQL 관련 처리를 할때도 INSERT/UPDATE/DELETE 구문을 실행한 후에 삽입/수정/삭제된 개수를 알수 있다.
이 개수를 확인하지 않아서 프로그램에 구멍이 생기는 경우가 많다.
적용된 개수를 반드시 확인하도록 한다.

좋은 코딩 습관 - 상태 기준을 엄격하게 잡기

제목 붙이기가 어렵네.

- 값을 비교해서 어떤 처리를 할때 아래와 같이 하면 0, 1 이외의 값이 넘어오는 경우는 처리가 안된다.(0, 1 일때만 처리해야 하는 경우 말고) - 사용자의 입력 오류던지 개발자의 실수 등으로 이런 경우는 충분히 발생할 수 있으므로 0, 1 이외의 경우도 처리해야 한다.

Javascrpt 개체 접근하기

개체가 여러개인 경우만 고려한 코딩이 많다.[각주:1]
개체가 없거나 1개인 경우도 고려해야 한다.

- 아래와 같이 호출하는 경우는 단일개체로 처리해야 한다. 배열이 아님.


  1. 항상 경계를 고려해야 함 [본문으로]

java.math.BigDecimal


2009-11-09 추가

- 소수점 없애기

Eclipse Code Assist

소스에 javadoc 형태의 주석을 달아두면 코딩시 참조할 수 있어 아주 편하다.

마우스를 올려두면 주석을 볼 수 있다.


Ctrl 키를 누른채 마우스를 올려두면 소스를 볼 수 있다.
(Eclipse 3.3 부터인가(?)는 Shift 가 기본 설정으로 되어 있음)


Code Assist 에서 주석을 볼 수 있다. javadoc 형태의 주석이 아니라면 보이지 않는다.
해당 소스로 이동해서 주석을 보지 않아도 확인 가능하다.