Exception: Saro::Dat::Error

Inherits:
StandardError
  • Object
show all
Defined in:
lib/saro/dat/error.rb

Overview

DAT 의 단일 오류 타입.

예전에는 정의만 되어 있고 아무도 쓰지 않았다. 대신 ArgumentError 와 RuntimeError 가 같은 조건에 뒤섞여 던져져서(예: "Invalid DAT: Format" 이 DatManager#parse 에서는 ArgumentError, DatManager._parse 에서는 RuntimeError) 호출부가 어느 쪽을 잡아야 할지 알 수 없었다.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, detail = nil, cause: nil) ⇒ Error

Returns a new instance of Error.



104
105
106
107
108
109
# File 'lib/saro/dat/error.rb', line 104

def initialize(code, detail = nil, cause: nil)
  @code = code
  @detail = detail
  @explicit_cause = cause
  super(detail ? "#{code}: #{detail}" : code)
end

Instance Attribute Details

#codeObject (readonly)

공개 계약인 오류 코드. 모든 공식 클라이언트에서 동일하다.



100
101
102
# File 'lib/saro/dat/error.rb', line 100

def code
  @code
end

#detailObject (readonly)

사람이 읽는 설명. 자유롭게 바꿔도 된다.



102
103
104
# File 'lib/saro/dat/error.rb', line 102

def detail
  @detail
end

Class Method Details

.code_of(e) ⇒ Object

어떤 예외에서든 DAT 오류 코드를 꺼낸다. DAT 오류가 아니면 nil 이다.



146
147
148
# File 'lib/saro/dat/error.rb', line 146

def code_of(e)
  e.is_a?(Error) ? e.code : nil
end

.wrap(code, detail, e) ⇒ Object

DAT 오류가 아닌 것을 감싼다. 이미 Error 면 그대로 둔다. 원본은 cause 로 반드시 보존한다.



152
153
154
155
# File 'lib/saro/dat/error.rb', line 152

def wrap(code, detail, e)
  return e if e.is_a?(Error)
  new(code, detail, cause: e)
end

Instance Method Details

#causeObject

Ruby 는 rescue 안에서 raise 하면 #cause 를 자동으로 채운다. 그 동작은 그대로 두고, 명시적으로 넘긴 하위 원인이 있으면 그쪽을 우선한다. DAT_MANAGER_NO_ISSUABLE_CERTIFICATE 의 사유 코드가 이 경로로 실린다.



114
115
116
# File 'lib/saro/dat/error.rb', line 114

def cause
  @explicit_cause || super
end

#inspectObject



140
141
142
# File 'lib/saro/dat/error.rb', line 140

def inspect
  "#<Saro::Dat::Error #{@code}#{@detail ? " #{@detail.inspect}" : ''}>"
end

#retryObject

:transient - 같은 입력으로 재시도하면 해소될 수 있다. 백오프 후 재시도. :permanent - 설정·입력·배포를 고쳐야 한다. 재시도하지 않는다. :state - 오류가 아닌 상태 신호. 흐름 제어에만 쓴다.

중간값을 두지 않는다 — 호출부가 분기할 수 없기 때문이다.



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/saro/dat/error.rb', line 123

def retry
  if @code == ErrorCode::MANAGER_NO_ISSUABLE_CERTIFICATE
    # 발급창 시작 전이면 기다리면 풀린다. 나머지 사유는 안 풀린다.
    c = cause
    return :transient if c.is_a?(Error) && c.code == ErrorCode::CERT_NOT_YET_ISSUABLE
    return :permanent
  end
  return :transient if ErrorCode::TRANSIENT.include?(@code)
  return :state if ErrorCode::STATE.include?(@code)
  :permanent
end

#security_event?Boolean

위조·변조 시도의 직접 증거. 다른 실패와 같은 경로로 로깅하지 않는다.

Returns:

  • (Boolean)


136
137
138
# File 'lib/saro/dat/error.rb', line 136

def security_event?
  ErrorCode::SECURITY.include?(@code)
end