Skip to content

feat: OPTIC-1265: Improve error pages #7196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 25 additions & 34 deletions label_studio/core/static/css/error.css
Original file line number Diff line number Diff line change
@@ -1,56 +1,35 @@
/* Compiled from App.styl */
.ls-global-error {
padding: 32px;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 15vh;
}
.ls-global-error__heidi {
display: block;
margin: 32px auto;
width: 812px;
}

.ls-global-error h1 {
text-transform: uppercase;
text-align: center;
font-size: 20px;
font-size: 48px;
}

.ls-global-error h2 {
font-size: 20px;
color: var(--red-6);
}
.ls-global-error__details {
background: #f5f5f5;
max-height: 320px;
overflow-y: auto;
white-space: pre-wrap;
margin: 16px 0;
padding: 16px;
font-size: 16px;
}

.ls-global-error__actions {
display: flex;
gap: 8px;
gap: 24px;
}
.ls-global-error__actions > * {
line-height: 1em;
}
.ls-global-error__slack {
margin-right: auto;
display: flex;
align-items: center;
}
.ls-global-error__slack img {
height: 16px;
width: 16px;
margin-right: 8px;
}

/* Styles for dedicated error page */
body > .ls-global-error {
font-size: 16px;
max-width: 600px;
margin: 0 auto;
}
/* Compiled from Button.styl */
/* Compiled from Button.style */
body > .ls-global-error button,
body > .ls-global-error .button {
height: 40px;
width: 129px;
border: none;
cursor: pointer;
padding: 0 16px;
Expand All @@ -65,3 +44,15 @@ body > .ls-global-error .button {
box-shadow: inset 0px -1px 0px rgba(0,0,0,0.1), inset 0px 0px 0px 1px rgba(0,0,0,0.15);
font-weight: 500;
}

body > .ls-global-error button:hover {
box-shadow: rgba(0, 0, 0, 0.05) 0px 2px 4px 0px, rgba(0, 0, 0, 0.1) 0px -1px 0px 0px inset, rgba(0, 0, 0, 0.2) 0px 0px 0px 1px inset;
}

body > .ls-global-error button.ls-global-error__primary_button {
background-color: #566fcf;
color: #fff;
}
body > .ls-global-error button.ls-global-error__primary_button:hover {
background-color: #4C5FA9;
}
201 changes: 201 additions & 0 deletions label_studio/core/static/images/heidi-403.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
201 changes: 201 additions & 0 deletions label_studio/core/static/images/heidi-404.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
201 changes: 201 additions & 0 deletions label_studio/core/static/images/heidi-500.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions label_studio/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
from drf_yasg.views import get_schema_view
from rest_framework.permissions import AllowAny, IsAuthenticated

handler500 = 'core.views.custom_500'

versions = collect_versions()
open_api_info = openapi.Info(
title='Label Studio API',
Expand Down
10 changes: 0 additions & 10 deletions label_studio/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import mimetypes
import os
import posixpath
import sys
from pathlib import Path
from wsgiref.util import FileWrapper

Expand All @@ -24,11 +23,9 @@
HttpResponse,
HttpResponseForbidden,
HttpResponseNotFound,
HttpResponseServerError,
JsonResponse,
)
from django.shortcuts import redirect, render, reverse
from django.template import loader
from django.utils._os import safe_join
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
Expand Down Expand Up @@ -118,13 +115,6 @@ def editor_files(request):
return HttpResponse(json.dumps(response), status=200)


def custom_500(request):
"""Custom 500 page"""
t = loader.get_template('500.html')
type_, value, tb = sys.exc_info()
return HttpResponseServerError(t.render({'exception': value}))


def samples_time_series(request):
"""Generate time series example for preview"""
time_column = request.GET.get('time', '')
Expand Down
29 changes: 0 additions & 29 deletions label_studio/templates/401.html

This file was deleted.

15 changes: 5 additions & 10 deletions label_studio/templates/403.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% load static %}

{% block page_labeling %}
<title>403 | Label Studio</title>
<title>403 | Label Studio</title>
{{ block.super }}
{% endblock %}

Expand All @@ -13,17 +13,12 @@

{% block content %}
<div class="ls-global-error">
<h1>Server error</h1>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/opossum_broken.svg' %}" height="111" alt="Heidi's down" />
<h2>403 Forbidden</h2>
<div class="ls-global-error__details">{{ exception }}</div>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/heidi-403.svg' %}" alt="Heidi's down" draggable="false" />
<h1>Uh oh, this is not permitted.</h1>
<h2>Here’s a few things you can try:</h2>
<p class="ls-global-error__actions">
<a class="ls-global-error__slack button" target="_blank" href="https://slack.labelstud.io/?source=product-403-error">
<img src="{{ settings.HOSTNAME }}{% static 'images/slack.png' %}" width="16" />
Ask on Slack
</a>
<button onClick="history.back()">Go Back</button>
<button onClick="location.reload()">Reload</button>
<button onClick="window.location.href='/'" class="ls-global-error__primary_button">Go to Home</button>
</p>
</div>
{% endblock %}
12 changes: 4 additions & 8 deletions label_studio/templates/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@

{% block content %}
<div class="ls-global-error">
<h1>Server error</h1>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/opossum_broken.svg' %}" height="111" alt="Heidi's down" />
<h2>404 Not Found</h2>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/heidi-404.svg' %}" alt="Heidi's down" draggable="false" />
<h1>Uh oh, this page doesn’t exist.</h1>
<h2>Here’s a few things you can try:</h2>
<p class="ls-global-error__actions">
<a class="ls-global-error__slack button" target="_blank" href="https://slack.labelstud.io/?source=product-404-error">
<img src="{{ settings.HOSTNAME }}{% static 'images/slack.png' %}" width="16" />
Ask on Slack
</a>
<button onClick="history.back()">Go Back</button>
<button onClick="location.reload()">Reload</button>
<button onClick="window.location.href='/'" class="ls-global-error__primary_button">Go to Home</button>
</p>
</div>
{% endblock %}
14 changes: 5 additions & 9 deletions label_studio/templates/500.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@

{% block content %}
<div class="ls-global-error">
<h1>Server error</h1>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/opossum_broken.svg' %}" height="111" alt="Heidi's down" />
<h2>500 Something went wrong</h2>
<div class="ls-global-error__details">{{ exception }}</div>
<img class="ls-global-error__heidi" src="{{ settings.HOSTNAME }}{% static 'images/heidi-500.svg' %}" alt="Heidi's down" draggable="false" />
<h1>Uh oh, something went wrong.</h1>
<h2>Here’s a few things you can try:</h2>
<p class="ls-global-error__actions">
<a class="ls-global-error__slack button" target="_blank" href="https://slack.labelstud.io/?source=product-500-error">
<img src="{{ settings.HOSTNAME }}{% static 'images/slack.png' %}" width="16" />
Ask on Slack
</a>
<button onClick="history.back()">Go Back</button>
<button onClick="location.reload()">Reload</button>
<button onClick="location.reload()">Refresh</button>
<button onClick="window.location.href='/'" class="ls-global-error__primary_button">Go to Home</button>
</p>
</div>
{% endblock %}
Loading