How To Handle Errors in a Flask Application

اختار الكاتب صندوق التمويل المجاني والمفتوح المصدر لتلقي تبرع كجزء من برنامج Write for DOnations.

مقدمة

Flask هو إطار عمل ويب خفيف الوزن بلغة بايثون يوفر الأدوات والميزات المفيدة لإنشاء تطبيقات الويب بلغة بايثون.

عند تطوير تطبيق ويب، ستواجه على الأرجح مواقف حيث يتصرف تطبيقك بطريقة تخالف ما كنت تتوقعه. قد تكتب اسم متغير بشكل خاطئ، أو تستخدم حلقة for بشكل غير صحيح، أو تنشئ عبارة if بطريقة ترفع استثناء بايثون، مثل استدعاء دالة قبل تعريفها، أو ببساطة البحث عن صفحة غير موجودة. ستجد أن تطوير تطبيقات Flask الخاصة بك أسهل وأم smoother إذا تعلمت كيفية التعامل مع الأخطاء والاستثناءات بشكل صحيح.

في هذا البرنامج التعليمي، ستقوم ببناء تطبيق ويب صغير يوضح كيفية التعامل مع الأخطاء الشائعة التي يواجهها المطورون عند تطوير تطبيق ويب. ستنشئ صفحات خطأ مخصصة، وتستخدم مدقق Flask لاستكشاف الأخطاء وإصلاحها، وتستخدم التسجيل لتتبع الأحداث في تطبيقك.

المتطلبات الأساسية

الخطوة 1 — استخدام مُصحح الأخطاء في Flask

في هذه الخطوة، ستنشئ تطبيقًا يحتوي على بعض الأخطاء وتشغله بدون وضع التصحيح لرؤية كيفية استجابة التطبيق. ثم ستشغله بوضع التصحيح وتستخدم مُصحح الأخطاء لاكتشاف أخطاء التطبيق.

مع تفعيل بيئة البرمجة الخاصة بك وتثبيت Flask، افتح ملفًا يسمى app.py للتحرير داخل دليل flask_app الخاص بك:

  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. ثم تقوم بإنشاء مثيل تطبيق Flask يسمى app. تستخدم الدالة المزخرفة @app.route() لإنشاء دالة مشاهدة تسمى index()، التي تستدعي الدالة render_template() كقيمة إرجاع، والتي بدورها تعرض قالبًا يسمى index.html. هناك خطأين في هذا الكود: الأول هو أنك لم تستورد الدالة render_template()، والثاني هو أن ملف القالب index.html غير موجود.

احفظ وأغلق الملف.

بعد ذلك، أعلم Flask بالتطبيق باستخدام متغير البيئة FLASK_APP باستخدام الأمر التالي (على Windows، استخدم set بدلاً من export):

  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. يمكنك أيضًا الاطلاع على دليل نشر Flask مع Gunicorn، أو هذا الدليل مع uWSGI، أو يمكنك استخدام منصة DigitalOcean App Platform لنشر تطبيق Flask الخاص بك باتباع كيفية نشر تطبيق Flask باستخدام Gunicorn على منصة التطبيقات.

  • وضع التصحيح معطل، مما يعني أن مصحح أخطاء Flask لا يعمل، ولن تتلقى رسائل خطأ مفيدة في تطبيقك. في بيئة الإنتاج، عرض الأخطاء التفصيلية يعرض تطبيقك للثغرات الأمنية.

  • الخادم يعمل على عنوان URL http://127.0.0.1:5000/. لإيقاف الخادم، استخدم 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_ENV إلى development، لتتمكن من تشغيل التطبيق في وضع التطوير (الذي يمكن تفعيل المصحح)، باستخدام الأمر التالي (على Windows، استخدم set بدلاً من export):

  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 هو رمز دخول تحتاجه لفتح وحدة التحكم في متصفحك (قشرة بايثون تفاعلية يمكنك الوصول إليها بالنقر على أيقونة الطرفية الصغيرة المحاطة بالصورة أدناه).

قم بتحديث صفحة الفهرس في متصفحك وسترى الصفحة التالية:

هنا، ترى رسالة الخطأ المعروضة بطريقة أسهل في الفهم. العنوان الأول يعطيك اسم استثناء بايثون الذي سبب المشكلة (NameError في هذه الحالة). السطر الثاني يعطيك السبب المباشر (render_template() غير معرّف، مما يعني أنه لم يتم استيراده في هذه الحالة). بعد ذلك، لديك تتبع المكالمات التي مرت بكود فلاسك الداخلي. اقرأ تتبع المكالمات من الأسفل للأعلى، لأن السطر الأخير في تتبع المكالمات عادة ما يحتوي على أهم المعلومات.

ملاحظة:
أيقونة الطرفية المحاطة تسمح لك بتشغيل كود بايثون في المتصفح على إطارات مختلفة. هذا مفيد عندما تريد التحقق من قيمة متغير كما تفعل في قشرة بايثون تفاعلية. عندما تنقر على أيقونة الطرفية، ستحتاج إلى كتابة رمز دخول مصحح الأخطاء الذي حصلت عليه عند تشغيل الخادم. لن تحتاج هذه القشرة التفاعلية في هذا الدرس.

لإصلاح مشكلة 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 يمتد من القالب الأساسي.

قم بإنشاء دليل templates، وهو الدليل الذي يبحث فيه Flask عن ملفات القوالب. ثم افتح ملف 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. ثم تقوم بتعيين عنوان للصفحة وعرضه في رأس H1 باستخدام الكتلة title، وعرض تحية في رأس H2.

مع تشغيل خادم التطوير، قم بتحديث صفحة الفهرس في متصفحك.

سترى أن التطبيق لم يعد يعرض أي أخطاء وتظهر صفحة الفهرس كما هو متوقع.

لقد استخدمت وضع التصحيح ورأيت كيفية التعامل مع رسائل الخطأ. بعد ذلك، ستقوم بإحباط طلب للرد برسالة خطأ من اختيارك، ورؤية كيفية الرد بصفحات خطأ مخصصة.

الخطوة 2 — إنشاء صفحات خطأ مخصصة

في هذه الخطوة، ستتعلم كيفية إحباط الطلبات والرد برسالة خطأ HTTP 404 لحالة طلب المستخدم لبيانات غير موجودة على الخادم. ستتعلم أيضًا كيفية إنشاء صفحات خطأ مخصصة للأخطاء الشائعة HTTP، مثل خطأ 404 Not Found، وخطأ 500 Internal Server Error.

لتوضيح كيفية إلغاء الطلبات والرد بصفحة خطأ HTTP 404 مخصصة، ستقوم بإنشاء صفحة تعرض بعض الرسائل. إذا لم تكن الرسالة المطلوبة موجودة، سترد بخطأ 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])

احفظ وأغلق الملف.

في الطريقة أعلاه، لديك متغير URL idx. هذا هو الفهرس الذي سيحدد أي رسالة سيتم عرضها. على سبيل المثال، إذا كانت العنوان URL هي /messages/0، سيتم عرض الرسالة الأولى (Message Zero). تستخدم int converter لقبول الأعداد الصحيحة الموجبة فقط، لأن متغيرات URL لها قيم سلسلة نصية افتراضية.

داخل وظيفة العرض message()، لديك قائمة بايثون عادية تسمى messages بثلاث رسائل. (في سيناريو العالم الحقيقي، ستأتي هذه الرسائل من قاعدة بيانات، واجهة برمجة تطبيقات، أو مصدر بيانات خارجي آخر.) ترجع الوظيفة إلى استدعاء وظيفة render_template() بوسيطتين، message.html كملف القالب، ومتغير message الذي سيتم تمريره إلى القالب. سيكون هذا المتغير عنصرًا من قائمة messages بناءً على قيمة متغير idx في URL.

بعد ذلك افتح ملف قالب جديد 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. تضيف عنوانًا (Messages) في عنوان H1، وتعرض قيمة المتغير message في عنوان H2.

مع تشغيل خادم التطوير، قم بزيارة الروابط التالية على متصفحك:

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

ستلاحظ أن H2 يحتوي على النص Message Zero، Message One، أو Message Two على التوالي في كل من الروابط الثلاثة الأولى. ومع ذلك، في الرابط الرابع، سيرد الخادم برسالة خطأ IndexError: list index out of range. في بيئة الإنتاج، كانت الرد سيكون 500 Internal Server Error، ولكن الرد المناسب هنا هو 404 Not Found للإشارة إلى أن الخادم لا يستطيع العثور على رسالة بفهرس 3.

يمكنك الرد بخطأ 404 باستخدام دالة abort() المساعدة في Flask. للقيام بذلك، افتح ملف app.py:

  1. nano app.py

عدل السطر الأول لاستيراد دالة abort(). ثم قم بتعديل دالة العرض message() بإضافة try ... except clause كما هو موضح في الأجزاء المميزة أدناه:

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 لتغليف الوظيفة. تحاول أولاً إرجاع قالب messages مع الرسالة التي تتوافق مع الفهرس في عنوان URL. إذا لم يكن هناك رسالة مقابلة للفهرس، سيتم رفع استثناء IndexError. ثم تستخدم عبارة except لالتقاط هذا الخطأ، وتستخدم abort(404) لإلغاء الطلب والرد بخطأ 404 Not Found في HTTP.

مع تشغيل خادم التطوير، استخدم متصفحك لإعادة الزيارة لعنوان URL الذي رد باستثناء IndexError سابقًا (أو قم بزيارة أي عنوان URL بفهرس أكبر من 2):

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() كمعالج خطأ مُخصص. تأخذ الدالة الخطأ كوسيطة، وتُرجع استدعاءً للدالة render_template() مع قالب يُسمى 404.html. ستنشئ هذا القالب لاحقًا، ويمكنك استخدام اسم آخر إذا أردت. تُرجع أيضًا العدد الصحيح 404 بعد استدعاء render_template(). هذا يُخبر Flask أن رمز الحالة في الاستجابة يجب أن يكون 404. إذا لم تضفه، سيكون رمز الحالة الافتراضي في الاستجابة 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 %}

احفظ وأغلق الملف.

مثل أي قالب آخر، تمتد على القالب الأساسي، تستبدل محتوى الكتل content و title، وتضيف كود HTML الخاص بك. هنا لديك عنوان <h1> كعنوان، وعلامة <p> مع رسالة خطأ مُخصصة تُخبر المستخدم أن الصفحة غير موجودة، ورسالة مساعدة للمستخدمين الذين ربما أدخلوا الرابط يدويًا.

يمكنك استخدام أي HTML، CSS، وJavaScript تريده في صفحات الخطأ بنفس الطريقة التي تستخدمها في القوالب الأخرى.

مع تشغيل خادم التطوير، استخدم متصفحك لإعادة زيارة الرابط التالي:

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 الخاص بك. بعد ذلك، ستتعلم كيفية استخدام التسجيل لتتبع الأحداث في تطبيقك. يساعد تتبع الأحداث على فهم كيفية تصرف الكود الخاص بك، مما يسهل عملية التطوير والإصلاح.

الخطوة 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: رمز حالة الاستجابة.

تساعدك هذه السجلات في تشخيص المشاكل التي تحدث في تطبيقك. يمكنك تسجيل معلومات أكثر عندما تريد معرفة المزيد من التفاصيل حول طلبات معينة باستخدام مُسجل app.logger الذي يوفره Flask.

مع التسجيل، يمكنك استخدام وظائف مختلفة للإبلاغ عن المعلومات على مستويات تسجيل مختلفة. كل مستوى يشير إلى حدث حدث بدرجة معينة من الخطورة. يمكن استخدام الوظائف التالية:

  • 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 level)، مع ذكر أن التطبيق الآن يتلقى رسالة بفهرس محدد. ثم تستخدم app.logger.error() لتسجيل حقيقة أن استثناء IndexError تم رفعه مع الفهرس المحدد الذي تسبب في المشكلة (ERROR level، لأن حدث خطأ).

زر الرابط التالي:

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 -

هنا ترى رسالة INFO app.logger.info() تسجيل، ورسالة DEBUG مع رقم الفهرس الذي قمت بتسجيله باستخدام app.logger.debug().

الآن زر رابطًا لرسالة لا توجد:

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 -

كما ترى، لديك سجلات INFO و DEBUG التي رأيتها من قبل، وسجل ERROR جديد لأن رسالة بفهرس 3 لا توجد.

تسجيل الأحداث والمعلومات التفصيلية والأخطاء يساعدك على تحديد مكان حدوث الخطأ ويجعل استكشاف الأخطاء وإصلاحها أسهل.

تعلمت في هذه الخطوة كيفية استخدام سجل 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