fix: better validation error messages (#3736)

This commit is contained in:
Vlad Stan
2026-01-21 14:28:57 +02:00
committed by GitHub
parent 5e79ca35ab
commit d2e8914835
5 changed files with 35 additions and 16 deletions
+1 -1
View File
@@ -109,7 +109,7 @@ def register_exception_handlers(app: FastAPI): # noqa: C901
logger.error(f"RequestValidationError: {exc!s}") logger.error(f"RequestValidationError: {exc!s}")
return render_html_error(request, exc) or JSONResponse( return render_html_error(request, exc) or JSONResponse(
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
content={"detail": str(exc)}, content={"detail": [dict(e) for e in exc.errors()]},
) )
@app.exception_handler(HTTPException) @app.exception_handler(HTTPException)
+1 -1
View File
File diff suppressed because one or more lines are too long
+29 -11
View File
@@ -114,6 +114,13 @@ window._lnbitsUtils = {
formatMsat(value) { formatMsat(value) {
return this.formatSat(value / 1000) return this.formatSat(value / 1000)
}, },
parseJSONSafe(str) {
try {
return JSON.parse(str)
} catch (e) {
return null
}
},
notifyApiError(error) { notifyApiError(error) {
if (!error.response) { if (!error.response) {
return console.error(error) return console.error(error)
@@ -123,17 +130,28 @@ window._lnbitsUtils = {
401: 'warning', 401: 'warning',
500: 'negative' 500: 'negative'
} }
Quasar.Notify.create({ let messages = error.response.data.detail
timeout: 5000, if (messages) {
type: types[error.response.status] || 'warning', messages = Array.isArray(messages)
message: ? messages.map(e => e.msg + ` (${e.loc?.join('/')})`)
error.response.data.message || error.response.data.detail || null, : (messages = [messages])
caption: } else {
[error.response.status, ' ', error.response.statusText] messages = [error.response.data.message || error.response.data.detail]
.join('') }
.toUpperCase() || null,
icon: null messages.forEach(message =>
}) Quasar.Notify.create({
timeout: 5000,
type: types[error.response.status] || 'warning',
message,
caption:
[error.response.status, ' ', error.response.statusText]
.join('')
.toUpperCase() || null,
icon: null,
closeBtn: true
})
)
}, },
search(data, q, field, separator) { search(data, q, field, separator) {
try { try {
+2 -2
View File
@@ -245,7 +245,7 @@ async def test_create_invoice_validates_used_currency(
) )
assert response.status_code == 400 assert response.status_code == 400
res_data = response.json() res_data = response.json()
assert "The provided unit is not supported" in res_data["detail"] assert "The provided unit is not supported" in res_data["detail"][0]["msg"]
# check POST /api/v1/payments: invoice creation for internal payments only # check POST /api/v1/payments: invoice creation for internal payments only
@@ -823,7 +823,7 @@ async def test_api_payments_pay_lnurl(client, adminkey_headers_from):
"/api/v1/payments/lnurl", json=lnurl_data, headers=adminkey_headers_from "/api/v1/payments/lnurl", json=lnurl_data, headers=adminkey_headers_from
) )
assert response.status_code == 400 assert response.status_code == 400
assert "value_error.url.scheme" in response.json()["detail"] assert "invalid or missing URL scheme" in response.json()["detail"][0]["msg"]
################################ Labels ################################ ################################ Labels ################################
+2 -1
View File
@@ -2044,5 +2044,6 @@ async def test_api_update_user_labels(http_client: AsyncClient):
assert response.status_code == 400 assert response.status_code == 400
data = response.json() data = response.json()
assert ( assert (
"""string does not match regex "([A-Za-z0-9 ._-]{1,100}$)""" in data["detail"] """string does not match regex "([A-Za-z0-9 ._-]{1,100}$)"""
in data["detail"][0]["msg"]
) )