fix: handle invalid date formats gracefully and add missing dialog descriptions
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 4m14s

- Wrap date.fromisoformat() in try/except in case_update tool — prevents
  unhandled ValueError from surfacing as 500; FastAPI now catches it as 422
- Add DialogDescription (sr-only) to 5 dialogs missing aria-describedby:
  documents-panel preview + delete, drafts-panel delete + feedback, link-related-dialog

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 15:53:01 +00:00
parent 1496e520fd
commit b368bce690
5 changed files with 34 additions and 17 deletions

View File

@@ -326,9 +326,15 @@ async def case_update(
if notes: if notes:
fields["notes"] = notes fields["notes"] = notes
if hearing_date: if hearing_date:
fields["hearing_date"] = date_type.fromisoformat(hearing_date) try:
fields["hearing_date"] = date_type.fromisoformat(hearing_date)
except ValueError as exc:
raise ValueError(f"Invalid hearing_date format: {hearing_date!r}") from exc
if decision_date: if decision_date:
fields["decision_date"] = date_type.fromisoformat(decision_date) try:
fields["decision_date"] = date_type.fromisoformat(decision_date)
except ValueError as exc:
raise ValueError(f"Invalid decision_date format: {decision_date!r}") from exc
if tags is not None: if tags is not None:
fields["tags"] = tags fields["tags"] = tags
if expected_outcome: if expected_outcome:

View File

@@ -6,6 +6,7 @@ import { Progress } from "@/components/ui/progress";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogDescription,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogFooter, DialogFooter,
@@ -127,6 +128,7 @@ function DocumentPreviewDialog({
<DialogContent className="sm:max-w-2xl max-h-[80vh] flex flex-col" dir="rtl"> <DialogContent className="sm:max-w-2xl max-h-[80vh] flex flex-col" dir="rtl">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-right">{displayName}</DialogTitle> <DialogTitle className="text-right">{displayName}</DialogTitle>
<DialogDescription className="sr-only">תצוגה מקדימה של תוכן המסמך</DialogDescription>
</DialogHeader> </DialogHeader>
<div className="flex-1 overflow-hidden"> <div className="flex-1 overflow-hidden">
{loading && ( {loading && (
@@ -184,6 +186,7 @@ function DeleteConfirmDialog({
<DialogContent dir="rtl"> <DialogContent dir="rtl">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-right">מחיקת מסמך</DialogTitle> <DialogTitle className="text-right">מחיקת מסמך</DialogTitle>
<DialogDescription className="sr-only">אישור מחיקת המסמך מהתיק</DialogDescription>
</DialogHeader> </DialogHeader>
<p className="text-sm text-ink-muted text-right"> <p className="text-sm text-ink-muted text-right">
האם למחוק את המסמך <strong>&ldquo;{displayName}&rdquo;</strong>? האם למחוק את המסמך <strong>&ldquo;{displayName}&rdquo;</strong>?

View File

@@ -8,6 +8,7 @@ import { Textarea } from "@/components/ui/textarea";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogDescription,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
@@ -323,6 +324,7 @@ export function DraftsPanel({
<DialogContent className="sm:max-w-sm" dir="rtl"> <DialogContent className="sm:max-w-sm" dir="rtl">
<DialogHeader> <DialogHeader>
<DialogTitle>מחיקת טיוטה</DialogTitle> <DialogTitle>מחיקת טיוטה</DialogTitle>
<DialogDescription className="sr-only">אישור מחיקת קובץ הטיוטה</DialogDescription>
</DialogHeader> </DialogHeader>
<p className="text-sm text-ink-muted"> <p className="text-sm text-ink-muted">
למחוק את הקובץ{" "} למחוק את הקובץ{" "}
@@ -493,6 +495,7 @@ function NewCaseFeedbackDialog({ caseNumber }: { caseNumber: string }) {
<DialogContent className="sm:max-w-lg" dir="rtl"> <DialogContent className="sm:max-w-lg" dir="rtl">
<DialogHeader> <DialogHeader>
<DialogTitle>הערת יו״ר תיק {caseNumber}</DialogTitle> <DialogTitle>הערת יו״ר תיק {caseNumber}</DialogTitle>
<DialogDescription className="sr-only">הוספת הערת יו״ר על בלוק בהחלטה</DialogDescription>
</DialogHeader> </DialogHeader>
<form onSubmit={handleSubmit} className="space-y-4 mt-2"> <form onSubmit={handleSubmit} className="space-y-4 mt-2">
<div className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-2 gap-3">

View File

@@ -6,6 +6,7 @@ import { toast } from "sonner";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogDescription,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
@@ -68,6 +69,7 @@ function LinkDialog({ caseId, currentRelated, open, onOpenChange }: DialogProps)
<DialogContent className="max-w-lg" dir="rtl"> <DialogContent className="max-w-lg" dir="rtl">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-navy">קשר החלטה קשורה</DialogTitle> <DialogTitle className="text-navy">קשר החלטה קשורה</DialogTitle>
<DialogDescription className="sr-only">חיפוש וקישור תקדים או החלטה קשורה לתיק</DialogDescription>
</DialogHeader> </DialogHeader>
<div className="space-y-3"> <div className="space-y-3">

View File

@@ -1378,21 +1378,24 @@ async def api_case_update(case_number: str, req: CaseUpdateRequest, background_t
existing = await db.get_case_by_number(case_number) existing = await db.get_case_by_number(case_number)
old_status = (existing or {}).get("status", "") old_status = (existing or {}).get("status", "")
result = await cases_tools.case_update( try:
case_number=case_number, result = await cases_tools.case_update(
status=req.status, case_number=case_number,
title=req.title, status=req.status,
subject=req.subject, title=req.title,
notes=req.notes, subject=req.subject,
hearing_date=req.hearing_date, notes=req.notes,
decision_date=req.decision_date, hearing_date=req.hearing_date,
tags=req.tags, decision_date=req.decision_date,
expected_outcome=req.expected_outcome, tags=req.tags,
appellants=req.appellants, expected_outcome=req.expected_outcome,
respondents=req.respondents, appellants=req.appellants,
property_address=req.property_address, respondents=req.respondents,
permit_number=req.permit_number, property_address=req.property_address,
) permit_number=req.permit_number,
)
except ValueError as exc:
raise HTTPException(422, str(exc))
try: try:
parsed = json.loads(result) parsed = json.loads(result)
except json.JSONDecodeError: except json.JSONDecodeError: