Open ASH-Bryan opened 6 years ago
Examples of some different ways this is being done currently:
handleResponse(status, headers, payload, requestData) {
if (isPresent(payload.responseStatus)) {
const serverError = payload.responseStatus;
const message = serverError.message;
serverError.errors.push({
detail: message,
});
return new InvalidError(serverError.errors);
}
return this._super(status, headers, payload, requestData);
}
handleResponse(status, headers, payload) {
if (status === 400) {
let message;
try {
message = { "detail": payload.responseStatus.message };
} catch (error) {
message = { "detail": this._getDefaultMessage() };
} finally {
payload.errors = [message];
}
return payload;
}
return this._super(...arguments);
}
handleResponse(status, headers, payload, requestData) {
if (this.isInvalid(status)) {
payload.errors = [{
detail: payload.responseStatus.message,
code: payload.responseStatus.errorCode
}];
}
return this._super(status, headers, payload, requestData);
}
handleResponse(status, headers, payload, requestData) {
let newPayload = payload;
if (isPresent(payload.responseStatus)) {
newPayload = payload.responseStatus;
newPayload.errors = [
{
detail: newPayload.message,
source: {
pointer: `data/attributes/${dasherize(newPayload.errorCode)}`
}
}
]
return new InvalidError(newPayload.errors);
}
return this._super(status, headers, newPayload, requestData);
}
handleResponse(status, headers, payload, requestData) {
if (status === 400 && payload.responseStatus) {
payload = payload.responseStatus;
payload.errors = [{ detail: payload.message }];
return new InvalidError(payload.errors);
}
return this._super(status, headers, payload, requestData);
}
handleResponse(status, headers, payload, requestData) {
if ((status === 400 || status === 500) && payload.responseStatus) {
const response = payload.responseStatus;
if(!isPresent(response.errors)) {
response.errors = [];
}
if(isPresent(response.message)) {
response.errors.push({
detail: response.message
});
}
return new InvalidError(response.errors);
}
return this._super(status, headers, payload, requestData);
}
Also let's decide on status codes - I believe that 422 is the only officially recognized status code for field validation errors.
For reference, here is the 'approved' service stack error format:
"responseStatus": {
"errorCode": "ArgumentException",
"message": "Invalid Request",
"stackTrace": "redacted",
"errors": [
{
"errorCode": "InValid",
"fieldName": "CurrentPassword",
"message": "Oops! Password is incorrect."
}
],
"meta": null
}
And here is the adapter method I wrote which will also give us access to the field-level errors. The above functions will only show top-level error messages. We could also branch this on the status code if we get back end to adhere to Ember's 422 code for validations:
handleResponse(status, headers, payload) {
if (status >= 400 && payload.responseStatus) {
const errors = [];
if (isEmpty(payload.responseStatus.errors)) {
//Top level error message only
errors.push(payload.responseStatus.message);
} else {
//Iterate through the field validations
payload.responseStatus.errors
.forEach(error => errors.push({
detail: error.message,
source: { pointer: error.fieldName }
}));
}
return new InvalidError(errors);
}
return this._super(...arguments);
}
Team agrees to table this standard until CRAFT and Front End team meeting discussions take place to determine which approach to take.
Table until after addon with adapter mixin is created to handle error responses.
Although we state in standards that validation error responses should conform to API standard, it does not appear that we are doing this on the back end. Our existing applications have adapter logic to reformat service stack error responses.
Is this the best approach?
If so, we need to agree on common adapter logic to handle this. Ideally it should be an addon.