Skip to content

Fix/pos validation error messages - #253

Draft
swafa-as wants to merge 3 commits into
developfrom
fix/pos-validation-error-messages
Draft

Fix/pos validation error messages#253
swafa-as wants to merge 3 commits into
developfrom
fix/pos-validation-error-messages

Conversation

@swafa-as

@swafa-as swafa-as commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #249 by ensuring actual Frappe validation error messages (such as insufficient stock, payment mismatch, or mandatory field errors) are extracted and displayed to the user instead of generic fallback strings like "There was an error.".

What Changed

  • @ury/core: Added a shared parseFrappeError(err, fallback) utility that extracts human-readable validation messages from:
    • _server_messages (handles multiple messages and strips HTML tags)
    • Python exception tracebacks (frappe.exceptions.ValidationError: ...)
    • Response .message, _error_message, or exc_type fallbacks
  • PaymentDialog: Updated handlePayment error catch block to surface backend make_invoice validation errors directly to the cashier, and cleaned up toast invocation.
  • OrderPanel & Orders: Refactored order sync, order cancel, and order edit error handlers to use parseFrappeError.
  • i18n: Added payment_failed translation key across English, Arabic, and French locales.

…handling

Adds a shared parseFrappeError(err, fallback) utility to @ury/core that
correctly extracts human-readable validation messages from Frappe API errors.

The frappe-js-sdk throws a plain object (not an Error instance) with the
error response data spread into it. Frappe places the actual user-facing
validation message in _server_messages (a doubly-JSON-encoded array) rather
than in the top-level .message field, which is typically a generic wrapper.

Parsing priority:
1. _server_messages — richest source from frappe.throw() / frappe.msgprint()
2. .message — if it is not the generic SDK fallback string
3. caller-supplied fallback string

Strips HTML tags from server messages since Frappe sometimes includes markup.

Closes part of: #249
…r flows

Uses the new parseFrappeError() utility from @ury/core to extract the
human-readable message from _server_messages across all three components
that handle Frappe API errors in the React POS v2.

PaymentDialog.tsx:
- Imports parseFrappeError and showToast from their proper packages
- Removes the dead window.showToast global hack (success path)
- Catch block now calls parseFrappeError() so make_invoice validation
  errors (e.g. insufficient stock, payment mismatch) surface to the
  user instead of the generic SDK fallback

OrderPanel.tsx:
- Removes inline _server_messages parsing that duplicated the logic now
  shared via parseFrappeError()
- Catch block reduced to a single parseFrappeError() call

Orders.tsx:
- Fixes cancel and edit error handlers which used err instanceof Error
  — since the SDK throws a plain object, this check always evaluated to
  false, silently discarding the real error in favour of the generic
  i18n fallback. Now uses parseFrappeError() correctly.

i18n:
- Adds errors.payment_failed key to en / ar / fr locale files

Fixes: #249
… error types

Expands parseFrappeError to extract and surface any Frappe validation error:
- Parses multiple server messages from frappe.msgprint / frappe.throw
- Preserves custom message titles if present
- Extracts error messages from Python exception traces (e.g. frappe.exceptions.ValidationError)
- Converts HTML breaks/paragraphs to clean multiline text before tag stripping
- Checks _error_message, top-level message, and exc_type fallbacks
@swafa-as
swafa-as marked this pull request as draft July 29, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generic Error Message Displayed During Payment Instead of Actual Stock Validation Error

2 participants