Commit 09895cd0 authored by Pierre Dittgen's avatar Pierre Dittgen

Fix and improve error handling on home page

parent 8e1b9787
{% extends "base_template.html" %}
{% block title %}Accueil{% endblock %}
{% block content %}
<div class="container">
{% for section in sections %}
{% if section.catalog %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description | safe }}</p>
{% endif %}
<form action="{{ url_for('custom_validator') }}" method="GET">
<div class="form-row">
<div class="form-group col-lg-9">
<select required name="schema_name" class="form-control">
<option disabled selected value="">Choisissez un schéma</option>
{% for item in section.catalog %}
<option {% if item.err %}disabled{% endif %}
value="{{ section.name }}.{{ item.name }}">{{ item.title }}</option>
{% endfor %}
</select>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">Valider un fichier</button>
{% for section in sections %} {% if section.catalog %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description | safe }}</p>
{% endif %}
<form action="{{ url_for('custom_validator') }}" method="GET">
<div class="form-row">
<div class="form-group col-lg-9">
<select required name="schema_name" class="form-control">
<option disabled selected value="">Choisissez un schéma</option>
{% for item in section.catalog %}
<option
{%
if
item.err
%}disabled{%
endif
%}
value="{{ section.name }}.{{ item.name }}"
>{{ item.title }}</option
>
{% endfor %}
</select>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">
Valider un fichier
</button>
</div>
</div>
</form>
</div>
{% elif section.err %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description | safe }}</p>
{% endif %}
<div class="alert alert-danger" role="alert">
Catalogue indisponible: {{ section.err | safe }}
</div>
</form>
</div>
{% elif section.err %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description }}</p>
{% endif %}
<div class="alert alert-danger" role="alert">
Catalogue indisponible: {{ section.err }}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %} {% endfor %}
<div class="my-5">
<h2>Schéma à la carte</h2>
<p class="text-muted">Indiquez ici l'URL d'un schéma que vous souhaitez utiliser pour valider un fichier.</p>
<form action="{{ url_for('custom_validator') }}" data-cy="custom_schema_form" method="GET">
<div class="form-row">
<div class="form-group col-lg-9">
<input
name="schema_url"
type="url"
class="form-control"
id="schema_url"
aria-describedby="urlHelpBlock"
placeholder="https://example.com/schema.json"
required
/>
<small id="urlHelpBlock" class="form-text text-muted">
Le schéma doit être au format
<a href="https://frictionlessdata.io/docs/table-schema/" target="_blank">Table Schema</a>.
</small>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">Valider un fichier</button>
<div class="my-5">
<h2>Schéma à la carte</h2>
<p class="text-muted">
Indiquez ici l'URL d'un schéma que vous souhaitez utiliser pour valider un
fichier.
</p>
<form
action="{{ url_for('custom_validator') }}"
data-cy="custom_schema_form"
method="GET"
>
<div class="form-row">
<div class="form-group col-lg-9">
<input
name="schema_url"
type="url"
class="form-control"
id="schema_url"
aria-describedby="urlHelpBlock"
placeholder="https://example.com/schema.json"
required
/>
<small id="urlHelpBlock" class="form-text text-muted">
Le schéma doit être au format
<a
href="https://frictionlessdata.io/docs/table-schema/"
target="_blank"
>Table Schema</a
>.
</small>
</div>
<div class="form-group col-lg-3">
<button type="submit" class="btn btn-primary">
Valider un fichier
</button>
</div>
</div>
</div>
</form>
</div>
</form>
</div>
{% for section in sections %}
{% if section.links %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description }}</p>
{% endif %}
<div class="row my-4">
{% for item in section.links %}
<div class="col-sm-4 mb-4">
<div class="card h-100">
<div class="card-body d-flex flex-column">
<h4 class="card-title">{{ item.title }}</h4>
<p class="card-text">{{ item.description }}</p>
<a
href="{{ item.website }}" target="_blank"
class="btn btn-outline-secondary mt-auto"
>Utiliser
<i class="fas fa-external-link-alt ml-1"></i>
{% for section in sections %} {% if section.links %}
<div class="my-5">
<h2>{{ section.title }}</h2>
{% if section.description %}
<p class="text-muted">{{ section.description }}</p>
{% endif %}
<div class="row my-4">
{% for item in section.links %}
<div class="col-sm-4 mb-4">
<div class="card h-100">
<div class="card-body d-flex flex-column">
<h4 class="card-title">{{ item.title }}</h4>
<p class="card-text">{{ item.description }}</p>
<a
href="{{ item.website }}"
target="_blank"
class="btn btn-outline-secondary mt-auto"
>Utiliser
<i class="fas fa-external-link-alt ml-1"></i>
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %} {% endfor %}
{% block page_scripts %}
<style>
/* Error message display */
.btn-xs {
padding: .25rem .4rem;
font-size: .875rem;
line-height: .5;
border-radius: .2rem;
}
#exception_info {
padding-top: 1.3em;
padding-bottom: 0;
margin-bottom: 0;
}
</style>
{% endblock %}
</div>
{% endblock %}
......@@ -22,6 +22,7 @@ from backports.datetime_fromisoformat import MonkeyPatch
from commonmark import commonmark
from flask import abort, make_response, redirect, render_template, request, url_for
from opendataschema import GitSchemaReference, by_commit_date
from validata_core import messages, repair
from . import app, config, schema_catalog_registry, tableschema_from_url
......@@ -591,6 +592,44 @@ def bytes_data(f):
return iob.getvalue()
def retrieve_schema_catalog(section):
"""Retrieve schema catalog and return formatted error if it fails."""
def format_error_message(err_message, exc):
"""Prepare a bootstrap error message with details if wanted."""
exception_text = '\n'.join([str(arg) for arg in exc.args])
return f"""{err_msg}
<div class="float-right">
<button type="button" class="btn btn-info btn-xs" data-toggle="collapse" data-target="#exception_info">détails</button>
</div>
<div id="exception_info" class="collapse">
<pre>{exception_text}</pre>
</div>
"""
try:
schema_catalog = get_schema_catalog(section['name'])
return (schema_catalog, None)
except Exception as exc:
log.exception(exc)
err_msg = "une erreur s'est produite"
if isinstance(exc, requests.ConnectionError):
err_msg = "problème de connexion"
elif isinstance(exc, json.decoder.JSONDecodeError):
err_msg = "format JSON incorrect"
elif isinstance(exc, jsonschema.exceptions.ValidationError):
err_msg = "le catalogue ne respecte pas le schéma de référence"
error_catalog = {
**{k: v for k,v in section.items() if k != 'catalog'},
"err": format_error_message(err_msg, exc)
}
return None, error_catalog
# Routes
......@@ -609,28 +648,18 @@ def home():
# section with only links to external validators
if "links" in section:
yield section
continue
# section with catalog
if not "catalog" in section:
# skip section
continue
# error while getting schema catatalog
try:
schema_catalog = get_schema_catalog(section['name'])
except Exception as exc:
log.exception(exc)
err_msg = "une erreur s'est produite"
if isinstance(exc, requests.ConnectionError):
err_msg = "problème de connexion"
elif isinstance(exc, json.decoder.JSONDecodeError):
err_msg = "format JSON incorrect"
elif isinstance(exc, jsonschema.exceptions.ValidationError):
err_msg = "le catalogue ne respecte pas le schéma de référence"
yield {
**{k: v for k,v in section.items() if k != 'catalog'},
"err": err_msg
}
# retrieving schema catatalog
schema_catalog, catalog_error = retrieve_schema_catalog(section)
if schema_catalog is None:
yield catalog_error
continue
# Working on catalog
schema_info_list = []
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment