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):
from Products.Formulator.Errors import FormValidationError, ValidationError
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)
# and use container.REQUEST just to introduce yet another global state. Maybe because
# container.REQUEST is used in other places.
......@@ -104,7 +98,7 @@ try:
# 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
# XXX TODO: Form-wide validation errors
return failWithMessage(
return context.Base_returnFailureWithMessage(
translate('Only ODT, ODS, Hal and HalRestricted skins are allowed for reports '\
'in Preferences - User Interface - Report Style'))
......@@ -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
if request_form.get('your_portal_skin', None) not in ("ODT", "ODS"):
# 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 '\
'"Report Style" set to "ODT" or "ODS"'))
......
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')
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id, REQUEST=None</string> </value>
<value> <string>form_id</string> </value>
</item>
<item>
<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:
# Pack errors into the request
field_errors = form.ErrorFields(validation_errors)
request.set('field_errors', field_errors)
request.RESPONSE.setStatus(400)
return context.Base_renderForm(dialog_id)
# XXX: this is a duplication from form validation code in Base_callDialogMethod
......@@ -68,6 +69,7 @@ try:
doaction_param_list['workflow_action'],
**doaction_param_list)
except ValidationFailed, error_message:
response_code = 403
if getattr(error_message, 'msg', None):
# use of Message class to store message+mapping+domain
message = error_message.msg
......@@ -77,14 +79,12 @@ except ValidationFailed, error_message:
message = str(message)
else:
message = str(error_message)
if len(message) > 2000: # too long message will generate a too long URI
# that would become an error.
log("Status message has been truncated")
message = "%s ..." % message[:(2000 - 4)]
return context.Base_returnFailureWithMessage(message, response_code, request)
except WorkflowException as error_message:
response_code = 403
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.")
return context.Base_redirect(form_id, keep_items={'portal_status_message': message}, **kw)
return context.Base_returnFailureWithMessage(message, response_code, request)
else:
raise
else:
......
......@@ -186,14 +186,22 @@
error_text = 'You do not have the permissions to edit the object';
} else if (error.target.status === 0) {
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
.push(function () {
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) {
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
......@@ -212,7 +220,8 @@
});
// if server validation of form data failed (indicated by response code 400)
// 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
.push(function () {
// when the server-side validation returns the error description
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.30841.12858.15274</string> </value>
<value> <string>965.50744.39391.46916</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1518535283.31</float>
<float>1519729953.99</float>
<string>UTC</string>
</tuple>
</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