-
Notifications
You must be signed in to change notification settings - Fork 67
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
IntegerField has an incomplete API [1 day] #1035
Comments
Related: https://github.com/vaadin/vaadin-date-picker/issues/748 (considered blocked by vaadin/flow#8242) |
I would break this down into two separate issue:
|
private static final SerializableFunction<String, Integer> PARSER = valueFormClient -> { | |
if (valueFormClient == null || valueFormClient.isEmpty()) { | |
return null; | |
} | |
try { | |
return Integer.parseInt(valueFormClient); | |
} catch (NumberFormatException e) { | |
return null; | |
} | |
}; |
It is worth considering that DatePicker
, TimePicker
, and some other Flow components already throw an exception when the filled date cannot be parsed:
Lines 50 to 53 in b1a0a21
private static final SerializableFunction<String, LocalTime> PARSER = valueFromClient -> { | |
return valueFromClient == null || valueFromClient.isEmpty() ? null | |
: LocalTime.parse(valueFromClient); | |
}; |
From that perspective, IntegerField
and BigDecimalField
could just do the same: throw NumberFormatException
when an invalid value is filled in the field. It would be pretty much in line with other Flow components. We need to keep in mind though that it will be a breaking change as exceptions may potentially be thrown somewhere the user wouldn't have expected them before.
Flow doesn't set min
and max
to MIN_INTEGER
and MAX_INTEGER
respectively for IntegerField
by default.
There is another aspect of the issue described in the ticket. It is about integer limits. They are different in Java and Javascript:
- It is about 2^53 - 1 in Javascript
- It is usually about 2^32 in Java.
So there can be a situation where the user fills in an integer on the client-side that gets correctly processed by JavaScript because it is within the Javascript integer limit whereas it cannot be processed on the server-side because it is over the Java integer limit. Considering that, it could probably make sense to have Flow set the min
and max
attributes of the integer field to the Integer.MIN_INTEGER
and Integer.MAX_INTEGER
respectively to force the client-side to keep numbers within the Java integer limit as long as custom limits are not set.
I see way more issues than two here. The API is unfinished in a lot of places. Not only is it a problem in the described component, but also in the DatePicker. This is clearly shown in the related and linked (unresolved!) issue of DatePicker. But not only there. All CustomComponents have the same issue. That is what I described above. And I proved it in another issue, which I can't find right now. The problem is not solved by throwing a Clearly this would be a breaking change. But unless it is implemented, it is a broken system! It is a very broken system, as there is not a single workaround. I - as a programmer/user of the API - can't do anything. Not a single |
There it is: #1076 unresolved, and linked with similar problem. And if you like, I can search for dozens of (still open) issues related to this problem, as it is always the same cause when the UI reacts weirdly due to swallowed exceptions. |
The validation mechanism has been improved in v24 so that now field components properly handle non-parsable values as errors, which is reflected to their invalid flag. See vaadin/platform#3066 (comment) for more details. @schweinchendick Can you please check if the issue still persists? |
I'm closing the issue, as there has been no activity over a month. Feel free to reopen if the issue still persists. |
Yes, the issue still persists (Vaadin Flow 24.1.3), because the API is still incomplete. The current (new) implementation is just a bad workaround with obvious flaws. You still get
The problem with the current workaround arises at the ValueChangeEvent. First try to enter "123456789012", observe the invalid field. Then give up and enter the empty string "", now wait for the ValueChangeEvent. You will never see any Notification as the value did not change from The API is broken. Still. Now with an incomplete workaround. And this dates back at least since Vaadin 6. |
Thank you for the feedback. It's a fair point that, currently, the components lack a mechanism that would allow distinguishing completely nonsensical input from input that is accepted on the client-side but still gets rejected by the server due to technical limitations, e.g. exceeding the Java Integer limit. It's by design that the value falls back to However, we could improve the validation mechanism to allow providing individual error messages in cases where the value was set to |
Description
There is no way to communicate invalid input to the user or the Java backend.
Steps to Reproduce
Given the following code
Steps not to reproduce
test.getValue()
would returnnull
in this caseExpected Results
There should be a way to communicate this error to the user or backend. How? The API is missing functionality for that.
Actual Results
The user is confused while staring at a number, which isn't the number the backend will work with from there. Neither is the field invalid nor is this state communicated to the user.
Browsers Affected
Any. It is not the fault of the browser.
Version
probably all versions.
Background
In the IntegerField.java there is a PARSER which swallows NumberFormatExceptions. It converts any invalid input silently to
null
. 123456789012 is not parse-able so this is somehow expected (from a programmer's perspective). But the programmer cannot react to that input in any way.The same problem arises with any component implementing
HasValue
. The API is not written to handle invalid input.T getValue()
does not allow to throw an exception. But there is always a possibility that converting the user's input into a semantic value does not work out.This is heavily related to https://github.com/vaadin/vaadin-date-picker/issues/748.
But this is also true for any
CustomField.generateModelValue()
. The user can enter strange things that are not convertible to a valid value. There may be a workaround for custom field by implementing the "null object pattern" but you then have to return a different null object for every call. Otherwise the ValueChange is not triggered as the null-object still is equal to the former null-object.Conclusion
The API must be extended to support exception handling. getValue() and generateModelValue() should allow to throw some ValueException which could then be handled by the framework. The exception could also arise directly from the client side and passed through to the Java backend.
Invalid user input shall not be discarded. It must be handled in a proper way. Either by the WebComponent, the Flow component or the programmer using the framework.
The current "solution" is like
try {} catch (Exception e) { e.printStacktrace() }
The text was updated successfully, but these errors were encountered: