Commit 9f6e7700 authored by Ayush Tiwari's avatar Ayush Tiwari

[erp5_web_renderjs_ui]: Check for portal_status_message for errors

In case there is an error and the target response if of type json, we
should check for the portal_status_message and display it.

[erp5_hal_json_style]:
Do not set HTTP response code for error in Base_renderForm.
Add new script Base_returnFailureMessage to return response header for HTTP code errors.
Also, Remove useless message trunacation
parent e708e403
...@@ -15,12 +15,6 @@ def isFieldType(field, type_name): ...@@ -15,12 +15,6 @@ def isFieldType(field, type_name):
from Products.Formulator.Errors import FormValidationError, ValidationError from Products.Formulator.Errors import FormValidationError, ValidationError
from ZTUtils import make_query from ZTUtils import make_query
def failWithMessage(message, request=None):
response = request.RESPONSE if request is not None else context.REQUEST.RESPONSE
response.setStatus(500)
response.setHeader("Content-type", "application/json; charset=utf-8")
return json.dumps({"portal_status_message": str(message)})
# Kato: I do not understand why we throw away REQUEST from parameters (hidden in **kw) # Kato: I do not understand why we throw away REQUEST from parameters (hidden in **kw)
# and use container.REQUEST just to introduce yet another global state. Maybe because # and use container.REQUEST just to introduce yet another global state. Maybe because
# container.REQUEST is used in other places. # container.REQUEST is used in other places.
...@@ -104,7 +98,7 @@ try: ...@@ -104,7 +98,7 @@ try:
# Form is OK, it's just this field - style so we return back form-wide error # Form is OK, it's just this field - style so we return back form-wide error
# for which we don't have support out-of-the-box thus we manually craft it # for which we don't have support out-of-the-box thus we manually craft it
# XXX TODO: Form-wide validation errors # XXX TODO: Form-wide validation errors
return failWithMessage( return context.Base_returnFailureWithMessage(
translate('Only ODT, ODS, Hal and HalRestricted skins are allowed for reports '\ translate('Only ODT, ODS, Hal and HalRestricted skins are allowed for reports '\
'in Preferences - User Interface - Report Style')) 'in Preferences - User Interface - Report Style'))
...@@ -204,7 +198,7 @@ if dialog_method != update_method and clean_kw.get('deferred_style', 0): ...@@ -204,7 +198,7 @@ if dialog_method != update_method and clean_kw.get('deferred_style', 0):
# Limit Reports in Deferred style to known working styles # Limit Reports in Deferred style to known working styles
if request_form.get('your_portal_skin', None) not in ("ODT", "ODS"): if request_form.get('your_portal_skin', None) not in ("ODT", "ODS"):
# RJS own validation - deferred option works here only with ODS/ODT skins # RJS own validation - deferred option works here only with ODS/ODT skins
return failWithMessage( return Base_returnFailureWithMessage(
translate('Deferred reports are possible only with preference '\ translate('Deferred reports are possible only with preference '\
'"Report Style" set to "ODT" or "ODS"')) '"Report Style" set to "ODT" or "ODS"'))
......
form = getattr(context, form_id) form = getattr(context, form_id)
request = REQUEST or context.REQUEST
# HAL JSON uses HTTP codes to communicate what the payload represents
if request.get('field_errors', None):
# HTTP400 means invalid form
request.RESPONSE.setStatus(400)
return context.ERP5Document_getHateoas(form=form, mode='form') return context.ERP5Document_getHateoas(form=form, mode='form')
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>form_id, REQUEST=None</string> </value> <value> <string>form_id</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
"""
Script to return json for response header while displying failure
"""
import json
response = request.RESPONSE if request is not None else context.REQUEST.RESPONSE
# Set the response code and header info in the response
response.setStatus(int(response_code))
response.setHeader("Content-type", "application/json; charset=utf-8")
return json.dumps({"portal_status_message": str(message)})
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>message, response_code=500, request=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_returnFailureWithMessage</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -21,6 +21,7 @@ except FormValidationError, validation_errors: ...@@ -21,6 +21,7 @@ except FormValidationError, validation_errors:
# Pack errors into the request # Pack errors into the request
field_errors = form.ErrorFields(validation_errors) field_errors = form.ErrorFields(validation_errors)
request.set('field_errors', field_errors) request.set('field_errors', field_errors)
request.RESPONSE.setStatus(400)
return context.Base_renderForm(dialog_id) return context.Base_renderForm(dialog_id)
# XXX: this is a duplication from form validation code in Base_callDialogMethod # XXX: this is a duplication from form validation code in Base_callDialogMethod
...@@ -68,6 +69,7 @@ try: ...@@ -68,6 +69,7 @@ try:
doaction_param_list['workflow_action'], doaction_param_list['workflow_action'],
**doaction_param_list) **doaction_param_list)
except ValidationFailed, error_message: except ValidationFailed, error_message:
response_code = 403
if getattr(error_message, 'msg', None): if getattr(error_message, 'msg', None):
# use of Message class to store message+mapping+domain # use of Message class to store message+mapping+domain
message = error_message.msg message = error_message.msg
...@@ -77,14 +79,12 @@ except ValidationFailed, error_message: ...@@ -77,14 +79,12 @@ except ValidationFailed, error_message:
message = str(message) message = str(message)
else: else:
message = str(error_message) message = str(error_message)
if len(message) > 2000: # too long message will generate a too long URI return context.Base_returnFailureWithMessage(message, response_code, request)
# that would become an error.
log("Status message has been truncated")
message = "%s ..." % message[:(2000 - 4)]
except WorkflowException as error_message: except WorkflowException as error_message:
response_code = 403
if str(error_message) == "No workflow provides the '${action_id}' action.": if str(error_message) == "No workflow provides the '${action_id}' action.":
message = translateString("Workflow state may have been updated by other user. Please try again.") message = translateString("Workflow state may have been updated by other user. Please try again.")
return context.Base_redirect(form_id, keep_items={'portal_status_message': message}, **kw) return context.Base_returnFailureWithMessage(message, response_code, request)
else: else:
raise raise
else: else:
......
...@@ -186,14 +186,22 @@ ...@@ -186,14 +186,22 @@
error_text = 'You do not have the permissions to edit the object'; error_text = 'You do not have the permissions to edit the object';
} else if (error.target.status === 0) { } else if (error.target.status === 0) {
error_text = 'Document was not saved! Resubmit when you are online or the document accessible'; error_text = 'Document was not saved! Resubmit when you are online or the document accessible';
} else if (error.target.status === 500 && error.target.response.type === "application/json") { }
// if the response type is json, then look for the status message
// sent from the portal. We prefer to have portal_status_message in
// all cases when we have error
if (error.target.response.type === 'application/json') {
promise_queue promise_queue
.push(function () { .push(function () {
return jIO.util.readBlobAsText(error.target.response); return jIO.util.readBlobAsText(error.target.response);
}) })
// Get the error_text from portal_status_message, if there is no
// portal_status_message, then use the default error_text
.push(function (response_text) { .push(function (response_text) {
var response = JSON.parse(response_text.target.result); var response = JSON.parse(response_text.target.result);
error_text = response.portal_status_message; // If there is no portal_status_message, use the default
// error_text
error_text = response.portal_status_message || error_text;
}); });
} }
// display translated error_text to user // display translated error_text to user
...@@ -212,7 +220,8 @@ ...@@ -212,7 +220,8 @@
}); });
// if server validation of form data failed (indicated by response code 400) // if server validation of form data failed (indicated by response code 400)
// we parse out field errors and display them to the user // we parse out field errors and display them to the user
if (error.target.status === 400) { if (error.target.status === 400 &&
error.target.response.type === 'application/hal+json') {
promise_queue promise_queue
.push(function () { .push(function () {
// when the server-side validation returns the error description // when the server-side validation returns the error description
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.30841.12858.15274</string> </value> <value> <string>965.50744.39391.46916</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1518535283.31</float> <float>1519729953.99</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment