diff --git a/.gitignore b/.gitignore
index 1521c8b..79f5085 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
dist
+dist_error
diff --git a/error/401.html b/error/401.html
deleted file mode 100644
index 110babe..0000000
--- a/error/401.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
- 401 - Unauthorized
-
-
-
-
-
-
-
-
- 401
- Non Autorisé
-
-
-
diff --git a/error/403.html b/error/403.html
deleted file mode 100644
index d4f2325..0000000
--- a/error/403.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
- 403 - Forbidden
-
-
-
-
-
-
-
-
- 403
- Interdit
-
-
-
diff --git a/error/404.html b/error/404.html
deleted file mode 100644
index d29dadf..0000000
--- a/error/404.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
- 404 - Not Found
-
-
-
-
-
-
-
-
- 404
- Introuvable
-
-
-
diff --git a/error/500.html b/error/500.html
deleted file mode 100644
index 4dac003..0000000
--- a/error/500.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
- 500 - Internal Server Error
-
-
-
-
-
-
-
-
- 500
- Erreur Serveur Interne
-
-
-
diff --git a/error/502.html b/error/502.html
deleted file mode 100644
index 8e27671..0000000
--- a/error/502.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
- 502 - Bad Gateway
-
-
-
-
-
-
-
-
- 502
- Passerelle Défectueuse
-
-
-
diff --git a/generate_errors.py b/generate_errors.py
new file mode 100644
index 0000000..5577ee5
--- /dev/null
+++ b/generate_errors.py
@@ -0,0 +1,45 @@
+from pprint import pp
+from pathlib import Path
+from urllib import request
+import re
+
+src = Path('src')
+root = src.joinpath('error')
+with root.joinpath('root.html').open('r') as root_file:
+ root_html = root_file.read()
+with root.joinpath('root.css').open('r') as root_file:
+ root_css = root_file.read()
+
+error = Path('dist_error')
+error.mkdir(exist_ok=True)
+
+for x in error.rglob('*'):
+ if x.is_file() or x.is_symlink(): x.unlink()
+
+req = request.Request(
+ 'https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html',
+ method='GET')
+
+with request.urlopen(req) as res:
+ raw = res.read().decode('utf-8')
+
+codes = (re.finditer(r"(?s)\s*(.*?)
', raw))
+
+nginx_head = ''
+nginx_body = ''
+
+for item in codes:
+ code, title, desc = item.groups()
+ with error.joinpath(f'{code}.html').open('w') as html:
+ html.write(root_html.format(code=code, title=title, desc=desc, style=root_css))
+ nginx_head += f'error_page {code} @error{code};\n'
+ nginx_body += f'location @error{code} {{\n'\
+ f'root {error.resolve()};\n'\
+ f'try_files /{code}.html /{code}.html;\n'\
+ 'internal;}\n'
+
+with error.joinpath(f'nginx.conf').open('w') as nginx_file:
+ nginx_file.write(f'{nginx_head}\n{nginx_body}\n\n'\
+ 'proxy_intercept_errors on;')
diff --git a/src/error/root.css b/src/error/root.css
new file mode 100644
index 0000000..e99c67e
--- /dev/null
+++ b/src/error/root.css
@@ -0,0 +1,51 @@
+html {
+ box-sizing: border-box;
+ text-align: center;
+}
+*, *::before, *::after {
+ box-sizing: inherit;
+}
+
+body {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ margin: 0;
+ color: #000000de;
+ font-family: Inter, sans-serif;
+}
+
+h1,h2 {
+ display: inline-block;
+ padding: 0 .2em;
+}
+h1 {
+ color: #d50000;
+}
+h2 {
+ text-align: left;
+ font-weight: 400;
+}
+
+figure {
+ display: block;
+ border-top: 5px #dedede solid;
+ text-align: left;
+}
+
+blockquote::after, blockquote::before {
+ font-weight: 800;
+ color: #dedede;
+}
+blockquote::before {
+ content: "«";
+}
+blockquote::after {
+ content: "»";
+}
+
+figcaption {
+ text-align: right;
+}
diff --git a/src/error/root.html b/src/error/root.html
new file mode 100644
index 0000000..ce82ebe
--- /dev/null
+++ b/src/error/root.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ {code} - {title}
+
+
+
+
+
+
+
+ {code}
+ {title}
+
+
+