본문 바로가기
WIKI 기술 지식 베이스

handle_errors 지시문

원문 보기 위키 갱신

handle_errors 지시문 (에러 핸들러 설정)

handle_errors 지시문은 에러 핸들러를 설정해요. 일반 HTTP 요청 핸들러가 에러를 반환하면 일반 처리가 중단되고 에러 핸들러가 호출돼요. 정적 에러 페이지, 템플릿 에러 페이지, 또는 다른 백엔드로 리버스 프록시해 에러를 처리할 수 있어요.

출처: Caddy 공식 문서

본문

에러 핸들러를 설정해요.

일반 HTTP 요청 핸들러가 에러를 반환하면 일반 처리가 중단되고 에러 핸들러가 호출돼요. 에러 핸들러는 일반 라우트와 똑같은 라우트를 이루며, 일반 라우트가 할 수 있는 모든 것을 할 수 있어요. 이는 HTTP 요청 중 에러를 처리할 때 큰 제어와 유연성을 제공해요. 예를 들어 정적 에러 페이지, 템플릿 에러 페이지를 서빙하거나, 다른 백엔드로 리버스 프록시해서 에러를 처리할 수 있어요.

다른 상태 코드를 다르게 처리하려면 지시문을 반복할 수 있어요. 상태 코드를 지정하지 않으면 어떤 에러든 매칭하며, 다른 에러 핸들러가 매칭되지 않을 때 폴백으로 동작해요.

요청의 context는 에러 라우트로 이어져요. 그래서 site root나 vars처럼 요청 context에 설정된 값은 에러 핸들러에서도 보존돼요. 또한 에러를 처리할 때 새로운 placeholder도 사용할 수 있어요.

에러로 분류되는 HTTP 상태로 응답을 쓸 수 있는 reverse_proxy 같은 특정 지시문은 에러 라우트를 트리거하지 않아요.

자신의 라우팅 결정에 따라 에러를 명시적으로 트리거하려면 error 지시문을 사용할 수 있어요.

문법 (Syntax)

handle_errors [<status_codes...>] {
	<directives...>
}
  • **<status_codes...>**는 처리 중인 에러에 매칭할 하나 이상의 HTTP 상태 코드예요. 상태 코드는 3자리 숫자이거나, 각각 400-499 또는 500-599 범위의 모든 상태 코드에 매칭하는 특수한 4xx 또는 5xx일 수 있어요. 상태 코드를 지정하지 않으면 어떤 에러든 매칭하며, 다른 에러 핸들러가 매칭되지 않을 때 폴백으로 동작해요.

  • **<directives...>**는 한 줄에 하나씩 나열하는 HTTP 핸들러 지시문 및 matcher 목록이에요.

Placeholders

에러를 처리하는 동안 다음 placeholder를 사용할 수 있어요. 이것들은 HTTP 서버 에러 라우트의 JSON 문서에서 찾을 수 있는 전체 placeholder의 Caddyfile 약어예요.

Placeholder 설명 (Description)
{err.status_code} 권장 HTTP 상태 코드
{err.status_text} 권장 상태 코드와 연결된 상태 텍스트
{err.message} 에러 메시지
{err.trace} 에러의 출처
{err.id} 이 에러 발생에 대한 식별자

예시 (Examples)

상태 코드에 기반한 커스텀 에러 페이지(예: 404 에러에 대해 404.html 페이지). handle_errors에서 실행될 때 file_server는 에러의 HTTP 상태 코드를 보존한다는 점에 유의해요(사이트에 site root를 미리 설정했다고 가정):

handle_errors {
	rewrite /{err.status_code}.html
	file_server
}

templates를 사용해 커스텀 에러 메시지를 쓰는 단일 에러 페이지:

handle_errors {
	rewrite /error.html
	templates
	file_server
}

일부 에러 코드에만 커스텀 에러 페이지를 제공하고 싶다면, file matcher로 커스텀 에러 파일의 존재를 미리 확인할 수 있어요:

handle_errors {
	@custom_err file /err-{err.status_code}.html /err.html
	handle @custom_err {
		rewrite {file_match.relative}
		file_server
	}
	respond "{err.status_code} {err.status_text}"
}

HTTP 에러 처리에 매우 능숙한 전문 서버로 리버스 프록시해서 하루를 더 즐겁게 보내봐요 😸:

handle_errors {
	rewrite /{err.status_code}
	reverse_proxy https://http.cat {
		replace_status {err.status_code}
	}
}

respond를 사용해 에러 코드와 이름을 반환하는 간단한 예:

handle_errors {
	respond "{err.status_code} {err.status_text}"
}

특정 에러 코드를 다르게 처리하려면:

handle_errors 404 410 {
	respond "It's a 404 or 410 error!"
}

handle_errors 5xx {
	respond "It's a 5xx error."
}

handle_errors {
	respond "It's another error"
}

위는 상태 코드에 대해 expression matcher를 사용하고 상호 배타성을 위해 handle을 사용하는 아래와 동일하게 동작해요:

handle_errors {
	@404-410 `{err.status_code} in [404, 410]`
	handle @404-410 {
		respond "It's a 404 or 410 error!"
	}

	@5xx `{err.status_code} >= 500 && {err.status_code} < 600`
	handle @5xx {
		respond "It's a 5xx error."
	}

	handle {
		respond "It's another error"
	}
}

더 알아보기 (Learn more)