Flask 应用程序中에서 에러를 처리하는 方法

저자는 Write for DOnations 프로그램의 일환으로 Free and Open Source Fund에 기부를 선택했습니다.

서론

Flask는 Python 언어로 웹 애플리케이션을 만들 때 유용한 도구와 기능을 제공하는 경량급 Python 웹 프레임워크입니다.

웹 애플리케이션을 개발할 때 애플리케이션이 예상과 다르게 동작하는 상황에 부딪히게 됩니다. 변수를 잘못 입력하거나 for 루프를 잘못 사용하거나 if 문을 잘못 구성하여 Python 예외를 발생시킬 수 있습니다. 예를 들어 함수를 선언하기 전에 호출하거나 존재하지 않는 페이지를 찾는 것과 같습니다. 오류와 예외를 적절하게 처리하는 방법을 배우면 Flask 애플리케이션 개발이 더 쉽고 원활해질 것입니다.

이 튜토리얼에서는 웹 애플리케이션 개발 시 마주치는 일반적인 오류를 처리하는 방법을 보여주는 작은 웹 애플리케이션을 구축할 것입니다. 사용자 정의 오류 페이지를 만들고, Flask 디버거를 사용하여 예외를 해결하고, 로깅을 사용하여 애플리케이션의 이벤트를 추적할 것입니다.

전제 조건

1단계 — Flask 디버거 사용

이 단계에서는 몇 가지 오류가 있는 애플리케이션을 만들어 디버그 모드 없이 실행하여 애플리케이션의 응답을 확인합니다. 그런 다음 디버그 모드를 켜고 디버거를 사용하여 애플리케이션 오류를 해결합니다.

프로그래밍 환경이 활성화되고 Flask가 설치된 상태에서 flask_app 디렉토리 내에 app.py라는 파일을 열어 편집하세요:

  1. nano app.py

다음 코드를 app.py 파일 안에 추가하세요:

flask_app/app.py
from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')

위의 코드에서 먼저 flask 패키지에서 Flask 클래스를 가져옵니다. 그런 다음 app이라는 Flask 애플리케이션 인스턴스를 생성합니다. @app.route() 데코레이터를 사용하여 index()라는 뷰 함수를 생성하고, 이 함수는 반환 값으로 render_template() 함수를 호출하여 index.html이라는 템플릿을 렌더링합니다. 이 코드에는 두 가지 오류가 있습니다: 첫 번째는 render_template() 함수를 가져오지 않았다는 것이고, 두 번째는 index.html 템플릿 파일이 존재하지 않는다는 것입니다.

파일을 저장하고 닫습니다.

다음으로, 다음 명령을 사용하여 FLASK_APP 환경 변수를 통해 Flask에 애플리케이션에 대해 알립니다 (Windows에서는 export 대신 set을 사용하세요):

  1. export FLASK_APP=app

그런 다음 flask run 명령을 사용하여 애플리케이션 서버를 실행합니다:

  1. flask run

터미널에 다음과 같은 정보가 표시됩니다:

Output
* Serving Flask app 'app' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

이 출력은 다음과 같은 정보를 제공합니다:

  • 제공되는 Flask 애플리케이션 (app.py 경우)

  • 여기서 production인 환경입니다. 경고 메시지는 이 서버가 프로덕션 배포를 위한 것이 아니라는 점을 강조합니다. 이 서버를 개발용으로 사용하고 있으므로 이 경고는 무시해도 되지만, 자세한 정보는 Flask 문서의 배포 옵션 페이지를 참조하십시오. Gunicorn을 사용한 Flask 배포 튜토리얼이나 uWSGI를 사용한 튜토리얼도 확인할 수 있으며, DigitalOcean App Platform을 사용하여 Flask 애플리케이션을 배포하려면 Gunicorn을 사용하여 App Platform에 Flask 앱을 배포하는 방법 튜토리얼을 따르면 됩니다.

  • 디버그 모드가 꺼져 있으므로 Flask 디버거가 실행되지 않으며, 애플리케이션에서 유용한 오류 메시지를 받을 수 없습니다. 프로덕션 환경에서 자세한 오류를 표시하면 애플리케이션이 보안 취약점에 노출됩니다.

  • 서버는 http://127.0.0.1:5000/ URL에서 실행 중입니다. 서버를 중지하려면 CTRL+C를 사용하세요. 하지만 아직은 하지 마세요.

이제 브라우저를 사용하여 인덱스 페이지를 방문하세요:

http://127.0.0.1:5000/

다음과 같은 메시지가 표시될 것입니다:

Output
Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

이것은 500 Internal Server Error로, 서버가 애플리케이션 코드에서 내부 오류를 만났다는 것을 나타내는 서버 오류 응답입니다.

터미널에서 다음과 같은 출력을 볼 수 있습니다:

Output
[2021-09-12 15:16:56,441] ERROR in app: Exception on / [GET] Traceback (most recent call last): File "/home/abd/.local/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app response = self.full_dispatch_request() File "/home/abd/.local/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/abd/.local/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request rv = self.dispatch_request() File "/home/abd/.local/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "/home/abd/python/flask/series03/flask_app/app.py", line 8, in index return render_template('index.html') NameError: name 'render_template' is not defined 127.0.0.1 - - [12/Sep/2021 15:16:56] "GET / HTTP/1.1" 500 -

위의 추적 정보는 내부 서버 오류를 발생시킨 코드를 통과합니다. NameError: name 'render_template' is not defined 줄은 문제의 근본 원인을 제공합니다: render_template() 함수가 가져오지 않았습니다.

여기서 볼 수 있듯이, 오류를 해결하기 위해 터미널로 이동해야 하므로 불편합니다.

개발 서버에서 디버그 모드를 활성화하여 더 나은 문제 해결 경험을 할 수 있습니다. 이렇게 하려면 CTRL+C로 서버를 중지하고 환경 변수 FLASK_ENVdevelopment로 설정하여 다음 명령을 사용하여 개발 모드에서 애플리케이션을 실행하세요 (Windows에서는 export 대신 set을 사용하세요):

  1. export FLASK_ENV=development

개발 서버를 실행하세요:

  1. flask run

터미널에서 다음과 유사한 출력을 볼 수 있습니다:

Output
* Serving Flask app 'app' (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 120-484-907

여기에서 환경이 이제 development로 설정되어 있고, 디버그 모드가 켜져 있으며, 디버거가 활성화되어 있음을 확인할 수 있습니다. Debugger PIN은 브라우저에서 콘솔의 잠금을 해제하는 데 필요한 PIN입니다(아래 이미지에서 동그라미로 표시된 작은 터미널 아이콘을 클릭하여 접근할 수 있는 대화형 Python 쉘).

브라우저에서 인덱스 페이지를 새로 고치면 다음 페이지가 나타납니다:

여기에서 더 쉽게 이해할 수 있는 방식으로 오류 메시지가 표시됩니다. 첫 번째 제목은 문제를 일으킨 Python 예외의 이름을 알려줍니다(NameError인 경우). 두 번째 줄은 직접적인 이유를 알려줍니다(render_template()이 정의되지 않았으므로 이 경우에는 가져오지 않았음). 그 다음에는 실행된 Flask 내부 코드를 통과하는 트레이스백이 있습니다. 트레이스백은 아래에서 위로 읽어야 합니다. 왜냐하면 트레이스백의 마지막 줄에는 보통 가장 유용한 정보가 있기 때문입니다.

참고:
동그라미로 표시된 터미널 아이콘을 통해 브라우저에서 다양한 프레임에 대해 Python 코드를 실행할 수 있습니다. 이는 Python 대화형 쉘에서 하듯이 변수의 값을 확인하려는 경우에 유용합니다. 터미널 아이콘을 클릭하면 서버를 실행할 때 받은 Debugger PIN 코드를 입력해야 합니다. 이 튜토리얼에서는 이 대화형 쉘이 필요하지 않습니다.

NameError 문제를 해결하려면 서버를 계속 실행하고, 새 터미널 창을 열어 환경을 활성화한 후 app.py 파일을 여세요:

  1. nano app.py

파일을 다음과 같이 수정하세요:

flask_app/app.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')

파일을 저장하고 닫으세요.

여기서 누락된 render_template() 함수를 가져왔습니다.

개발 서버가 실행 중인 상태에서 브라우저의 인덱스 페이지를 새로 고침하세요.

이번에는 다음과 같은 정보가 포함된 오류 페이지가 나타납니다:

Output
jinja2.exceptions.TemplateNotFound jinja2.exceptions.TemplateNotFound: index.html

이 오류 메시지는 index.html 템플릿이 존재하지 않음을 나타냅니다.

이 문제를 해결하려면 코드 반복을 피하기 위해 다른 템플릿들이 상속받을 base.html 템플릿 파일을 만든 다음, 기본 템플릿을 확장하는 index.html 템플릿을 만들어야 합니다.

Flask가 템플릿 파일을 찾는 디렉토리인 templates 디렉토리를 생성하고, 좋아하는 편집기를 사용하여 base.html 파일을 여세요:

  1. mkdir templates
  2. nano templates/base.html

다음 코드를 base.html 파일에 추가하세요:

flask_app/templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('index') }}">FlaskApp</a>
        <a href="#">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

파일을 저장하고 닫으세요.

이 기본 템플릿에는 다른 템플릿에서 재사용할 모든 HTML 기본 구조가 포함되어 있습니다. title 블록은 각 페이지의 제목을 설정하기 위해 대체되며, content 블록은 각 페이지의 내용으로 대체됩니다. 네비게이션 바에는 url_for() 헬퍼 함수를 사용하여 index() 뷰 함수에 연결하는 인덱스 페이지용 링크와, 애플리케이션에 포함하기로 선택한 경우 정보 페이지용 링크가 있습니다.

다음으로, 기본 템플릿을 상속받는 index.html이라는 템플릿 파일을 엽니다.

  1. nano templates/index.html

다음 코드를 추가하세요:

flask_app/templates/index.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Index {% endblock %}</h1>
    <h2>Welcome to FlaskApp!</h2>
{% endblock %}

파일을 저장하고 닫습니다.

위의 코드에서 기본 템플릿을 확장하고 content 블록을 재정의합니다. 그런 다음 title 블록을 사용하여 페이지 제목을 설정하고 H1 헤더에 표시하며, H2 헤더에 인사말을 표시합니다.

개발 서버를 실행하는 동안 브라우저에서 인덱스 페이지를 새로 고칩니다.

애플리케이션에 더 이상 오류가 표시되지 않고 인덱스 페이지가 예상대로 표시되는 것을 볼 수 있습니다.

이제 디버그 모드를 사용하고 오류 메시지를 처리하는 방법을 살펴보았습니다. 다음으로, 선택한 오류 메시지로 요청을 중단하고 사용자 정의 오류 페이지로 응답하는 방법을 살펴보겠습니다.

2단계 — 사용자 정의 오류 페이지 생성

이 단계에서는 사용자가 서버에 존재하지 않는 데이터를 요청할 때 요청을 중단하고 404 HTTP 오류 메시지로 응답하는 방법을 배웁니다. 또한 404 Not Found 오류 및 500 Internal Server Error 오류와 같은 일반적인 HTTP 오류에 대한 사용자 정의 오류 페이지를 만드는 방법도 배웁니다.

요청을 중단하고 사용자 정의 404 HTTP 오류 페이지로 응답하는 방법을 보여주기 위해 몇 가지 메시지를 표시하는 페이지를 만들 것입니다. 요청된 메시지가 존재하지 않으면 404 오류로 응답합니다.

먼저 app.py 파일을 열어 메시지 페이지에 대한 새로운 경로를 추가하세요:

  1. nano app.py

파일 끝에 다음 경로를 추가하세요:

flask_app/app.py
# ...

@app.route('/messages/<int:idx>')
def message(idx):
    messages = ['Message Zero', 'Message One', 'Message Two']
    return render_template('message.html', message=messages[idx])

파일을 저장하고 닫습니다.

위의 경로에서 idx라는 URL 변수가 있습니다. 이것은 어떤 메시지가 표시될지 결정하는 인덱스입니다. 예를 들어, URL이 /messages/0이면 첫 번째 메시지(Message Zero)가 표시됩니다. URL 변수는 기본적으로 문자열 값을 가지므로 int 변환기를 사용하여 양의 정수만 허용합니다.

message() 뷰 함수 내부에는 세 개의 메시지가 있는 일반적인 Python 리스트인 messages가 있습니다. (실제 시나리오에서는 이러한 메시지가 데이터베이스, API 또는 다른 외부 데이터 소스에서 제공됩니다.) 이 함수는 message.html을 템플릿 파일로 사용하고 message 변수를 템플릿에 전달하는 두 개의 인수와 함께 render_template() 함수를 호출합니다. 이 변수는 URL에서 idx 변수의 값에 따라 messages 리스트의 항목을 가질 것입니다.

다음으로 새로운 message.html 템플릿 파일을 엽니다:

  1. nano templates/message.html

다음 코드를 추가하세요:

flask_app/templates/message.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Messages {% endblock %}</h1>
    <h2>{{ message }}</h2>
{% endblock %}

파일을 저장하고 닫습니다.

위의 코드에서 기본 템플릿을 확장하고 content 블록을 재정의합니다. H1 제목에 제목(Messages)을 추가하고, H2 제목에 message 변수의 값을 표시합니다.

개발 서버가 실행 중인 상태에서 브라우저에서 다음 URL을 방문하세요:

http://127.0.0.1:5000/messages/0
http://127.0.0.1:5000/messages/1
http://127.0.0.1:5000/messages/2
http://127.0.0.1:5000/messages/3

처음 세 URL에서 H2에 각각 Message Zero, Message One 또는 Message Two라는 텍스트가 포함되어 있음을 알 수 있습니다. 그러나 네 번째 URL에서는 서버가 IndexError: list index out of range 오류 메시지와 함께 응답할 것입니다. 프로덕션 환경에서는 500 Internal Server Error가 응답되었겠지만, 여기서 적절한 응답은 서버가 3 인덱스의 메시지를 찾을 수 없다는 것을 나타내는 404 Not Found입니다.

Flask의 abort() 헬퍼 함수를 사용하여 404 오류로 응답할 수 있습니다. 이를 위해 app.py 파일을 엽니다:

  1. nano app.py

첫 번째 줄을 편집하여 abort() 함수를 가져옵니다. 그런 다음 try ... except을 추가하여 message() 뷰 함수를 편집합니다. 아래 강조 표시된 부분과 같이 편집합니다:

flask_app/app.py
from flask import Flask, render_template, abort

# ...
# ...


@app.route('/messages/<int:idx>')
def message(idx):
    messages = ['Message Zero', 'Message One', 'Message Two']
    try:
        return render_template('message.html', message=messages[idx])
    except IndexError:
        abort(404)

파일을 저장하고 닫습니다.

위의 코드에서 abort() 함수를 가져옵니다. 이 함수는 요청을 중단하고 오류에 응답하는 데 사용합니다. message() 뷰 함수에서 try ... except 절로 함수를 감쌉니다. 먼저 URL의 인덱스에 해당하는 메시지와 함께 messages 템플릿을 반환하려고 시도합니다. 인덱스에 해당하는 메시지가 없으면 IndexError 예외가 발생합니다. 그런 다음 except 절을 사용하여 해당 오류를 잡고 abort(404)를 사용하여 요청을 중단하고 404 Not Found HTTP 오류로 응답합니다.

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 이전에 IndexError를 응답한 URL을 다시 방문하세요(또는 2보다 큰 인덱스를 가진 모든 URL을 방문하세요):

http://127.0.0.1:5000/messages/3

다음과 같은 응답이 표시됩니다:

Not Found

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

이제 서버가 요청한 메시지를 찾을 수 없다는 더 나은 오류 메시지가 표시됩니다.

다음으로, 404 오류 페이지와 500 오류 페이지를 위한 템플릿을 만들 것입니다.

먼저, 특수한 @app.errorhandler() 데코레이터로 404 오류에 대한 핸들러로 함수를 등록합니다. 편집을 위해 app.py 파일을 엽니다:

nano app.py

다음과 같이 강조 표시된 부분을 추가하여 파일을 편집합니다:

flask_app/app.py
from flask import Flask, render_template, abort

app = Flask(__name__)


@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/messages/<int:idx>')
def message(idx):
    messages = ['Message Zero', 'Message One', 'Message Two']
    try:
        return render_template('message.html', message=messages[idx])
    except IndexError:
        abort(404)

파일을 저장하고 닫습니다.

여기서 @app.errorhandler() 데코레이터를 사용하여 page_not_found() 함수를 사용자 정의 오류 처리기로 등록합니다. 이 함수는 오류를 인수로 받아 404.html이라는 템플릿과 함께 render_template() 함수를 호출하는 것을 반환합니다. 이 템플릿은 나중에 만들게 되며, 원하는 경우 다른 이름을 사용할 수도 있습니다. 또한 render_template() 호출 후에 정수 404를 반환합니다. 이는 응답의 상태 코드가 404여야 함을 Flask에 알려줍니다. 이를 추가하지 않으면 기본 상태 코드 응답은 200이 되어 요청이 성공했음을 의미합니다.

다음으로, 새로운 404.html 템플릿을 엽니다:

  1. nano templates/404.html

다음 코드를 추가합니다:

flask_app/templates/404.html
{% extends 'base.html' %}

{% block content %}
        <h1>{% block title %} 404 Not Found. {% endblock %}</h1>
        <p>OOPS! Sammy couldn't find your page; looks like it doesn't exist.</p>
        <p>If you entered the URL manually, please check your spelling and try again.</p>
{% endblock %}

파일을 저장하고 닫습니다.

다른 템플릿과 마찬가지로 기본 템플릿을 확장하고 contenttitle 블록의 내용을 대체하며 자신만의 HTML 코드를 추가합니다. 여기서는 제목으로 <h1> 제목을 사용하고, 페이지를 찾을 수 없다는 사용자 정의 오류 메시지가 있는 <p> 태그와 URL을 직접 입력한 사용자를 위한 도움말 메시지를 추가했습니다.

다른 템플릿에서와 마찬가지로 오류 페이지에 원하는 HTML, CSS, JavaScript를 사용할 수 있습니다.

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 다음 URL을 다시 방문하세요:

http://127.0.0.1:5000/messages/3

이제 페이지에 기본 템플릿에 있는 탐색 모음과 사용자 정의 오류 메시지가 표시됩니다.

마찬가지로, 500 Internal Server Error 오류에 대한 사용자 지정 오류 페이지를 추가할 수 있습니다. app.py 파일을 엽니다:

  1. nano app.py

다음 오류 핸들러를 404 오류 핸들러 아래에 추가하세요:

flask_app/app.py
# ...

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_error(error):
    return render_template('500.html'), 500

# ...

여기서는 404 오류 핸들러에서 사용한 것과 동일한 패턴을 사용합니다. app.errorhandler() 데코레이터를 500 인수와 함께 사용하여 internal_error() 함수를 오류 핸들러로 만듭니다. 500.html 템플릿을 렌더링하고 상태 코드 500로 응답합니다.

그런 다음 사용자 지정 오류가 어떻게 표시되는지 보여주기 위해 파일 끝에 500 HTTP 오류를 응답하는 경로를 추가합니다. 이 경로는 디버거가 실행 중인지 여부에 관계없이 항상 500 Internal Server Error를 발생시킵니다:

flask_app/app.py

# ...
@app.route('/500')
def error500():
    abort(500)

여기서는 /500 경로를 만들고 abort() 함수를 사용하여 500 HTTP 오류로 응답합니다.

파일을 저장하고 닫습니다.

다음으로, 새로운 500.html 템플릿을 엽니다:

  1. nano templates/500.html

다음 코드를 추가하세요:

flask_app/templates/500.html
{% extends 'base.html' %}

{% block content %}
        <h1>{% block title %} 500 Internal Server Error {% endblock %}</h1>
        <p>OOOOPS! Something went wrong on the server.</p>
        <p>Sammy is currently working on this issue. Please try again later.</p>
{% endblock %}

파일을 저장하고 닫습니다.

여기서는 404.html 템플릿에서 했던 것과 동일한 작업을 수행합니다. 기본 템플릿을 확장하고 콘텐츠 블록을 제목과 내부 서버 오류에 대해 사용자에게 알리는 두 개의 사용자 지정 메시지로 대체합니다.

개발 서버가 실행 중일 때, 500 오류를 응답하는 경로를 방문하세요:

http://127.0.0.1:5000/500

사용자 정의 페이지가 일반 오류 페이지 대신 나타납니다.

이제 Flask 애플리케이션에서 HTTP 오류에 대한 사용자 정의 오류 페이지를 사용하는 방법을 알게 되었습니다. 다음으로, 애플리케이션의 이벤트를 추적하기 위해 로깅을 사용하는 방법을 배우게 될 것입니다. 이벤트 추적은 코드가 어떻게 동작하는지 이해하는 데 도움이 되며, 이는 개발 및 문제 해결에 도움이 됩니다.

3단계 — 애플리케이션에서 이벤트 추적을 위한 로깅 사용

이번 단계에서는 서버가 실행되고 애플리케이션이 사용될 때 발생하는 이벤트를 추적하기 위해 로깅을 사용하여 애플리케이션 코드에서 무슨 일이 일어나고 있는지 확인하고 오류를 더 쉽게 해결할 수 있습니다.

개발 서버가 실행될 때마다 로그를 본 적이 있을 것입니다. 보통 이런 식으로 보입니다:

127.0.0.1 - - [21/Sep/2021 14:36:45] "GET /messages/1 HTTP/1.1" 200 -
127.0.0.1 - - [21/Sep/2021 14:36:52] "GET /messages/2 HTTP/1.1" 200 -
127.0.0.1 - - [21/Sep/2021 14:36:54] "GET /messages/3 HTTP/1.1" 404 -

이 로그에서 다음 정보를 확인할 수 있습니다:

  • 127.0.0.1: 서버가 실행되는 호스트.
  • [21/Sep/2021 14:36:45]: 요청의 날짜와 시간.
  • GET: HTTP 요청 메서드. 이 경우, GET은 데이터를 검색하는 데 사용됩니다.
  • /messages/2: 사용자가 요청한 경로.
  • HTTP/1.1: HTTP 버전.
  • 200 또는 404: 응답의 상태 코드.

이러한 로그들은 애플리케이션에서 발생하는 문제를 진단하는 데 도움이 됩니다. 특정 요청에 대한 자세한 정보를 알고 싶을 때 Flask가 제공하는 app.logger를 사용하여 더 많은 정보를 기록할 수 있습니다.

로깅을 통해 다양한 로깅 수준에 따라 정보를 보고하는 다양한 함수를 사용할 수 있습니다. 각 수준은 특정 정도의 심각성을 가진 이벤트를 나타냅니다. 다음 함수들을 사용할 수 있습니다:

  • app.logger.debug(): 이벤트에 대한 상세 정보.
  • app.logger.info(): 예상대로 작동하고 있음을 확인.
  • app.logger.warning(): 예상치 못한 일이 발생했음을 나타냅니다(예: “디스크 공간 부족”), 하지만 애플리케이션은 정상적으로 작동합니다.
  • app.logger.error(): 애플리케이션의 일부에서 오류가 발생했습니다.
  • app.logger.critical(): 치명적인 오류; 전체 애플리케이션이 작동을 중지할 수 있습니다.

Flask 로거를 사용하는 방법을 시연하기 위해 app.py 파일을 열어 몇 가지 이벤트를 기록하세요:

  1. nano app.py

message() 뷰 함수를 다음과 같이 수정하세요:

flask_app/app.py

# ...

@app.route('/messages/<int:idx>')
def message(idx):
    app.logger.info('Building the messages list...')
    messages = ['Message Zero', 'Message One', 'Message Two']
    try:
        app.logger.debug('Get message with index: {}'.format(idx))
        return render_template('message.html', message=messages[idx])
    except IndexError:
        app.logger.error('Index {} is causing an IndexError'.format(idx))
        abort(404)

# ...

파일을 저장하고 닫으세요.

여기에서 여러 수준의 몇 가지 이벤트를 기록했습니다. 예상대로 작동하는 이벤트를 기록하기 위해 app.logger.info()를 사용합니다(이는 INFO 수준입니다). 상세 정보를 위해 app.logger.debug()를 사용하여 애플리케이션이 특정 인덱스로 메시지를 받고 있다고 언급합니다(DEBUG 수준). 그런 다음 app.logger.error()를 사용하여 IndexError 예외가 발생했음을 기록하고, 문제를 일으킨 특정 인덱스를 언급합니다(ERROR 수준, 오류가 발생했기 때문에).

다음 URL을 방문하세요:

http://127.0.0.1:5000/messages/1

서버가 실행 중인 터미널에 다음 정보가 표시됩니다:

Output
[2021-09-21 15:17:02,625] INFO in app: Building the messages list... [2021-09-21 15:17:02,626] DEBUG in app: Get message with index: 1 127.0.0.1 - - [21/Sep/2021 15:17:02] "GET /messages/1 HTTP/1.1" 200 -

여기에서 app.logger.info()가 기록한 INFO 메시지와 app.logger.debug()를 사용하여 기록한 인덱스 번호가 포함된 DEBUG 메시지를 볼 수 있습니다.

이제 존재하지 않는 메시지의 URL을 방문하세요:

http://127.0.0.1:5000/messages/3

터미널에 다음 정보가 표시됩니다:

Output
[2021-09-21 15:33:43,899] INFO in app: Building the messages list... [2021-09-21 15:33:43,899] DEBUG in app: Get message with index: 3 [2021-09-21 15:33:43,900] ERROR in app: Index 3 is causing an IndexError 127.0.0.1 - - [21/Sep/2021 15:33:43] "GET /messages/3 HTTP/1.1" 404 -

보시다시피, 이전에 본 INFODEBUG 로그와 인덱스가 3인 메시지가 존재하지 않아 새로운 ERROR 로그가 있습니다.

이벤트, 상세 정보 및 오류를 기록하면 문제가 발생한 위치를 식별하고 문제 해결을 더 쉽게 할 수 있습니다.

이 단계에서 당신은 Flask 로거를 사용하는 방법을 배웠습니다. 로깅에 대한 더 나은 이해를 위해 Python 3에서 로깅을 사용하는 방법을 확인해보세요. 로깅에 대한 심층적인 이해를 원한다면 Flask 로깅 문서Python 로깅 문서를 참조하세요.

결론

이제 Flask에서 디버그 모드를 사용하는 방법과, Flask 웹 애플리케이션을 개발할 때 마주칠 수 있는 일반적인 오류를 해결하고 수정하는 방법을 알게 되었습니다. 또한 일반적인 HTTP 오류에 대한 사용자 정의 오류 페이지를 만들었고, Flask 로거를 사용하여 애플리케이션의 이벤트를 추적하여 애플리케이션의 동작을 검사하고 이해하는 데 도움을 주었습니다.

Flask에 대해 더 많은 정보를 원한다면 Flask 토픽 페이지를 확인해보세요.

Source:
https://www.digitalocean.com/community/tutorials/how-to-handle-errors-in-a-flask-application