mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-25 09:03:12 +03:00
🐛 Fixed missing error notification when attempting to activate an invalid theme
no issue - updates error handling to work with new v2 error response formats - `.errorType` -> `.error` - `.errorDetails` -> `.details`
This commit is contained in:
parent
98a93b5251
commit
d0a834b477
@ -129,7 +129,7 @@ export default ModalComponent.extend({
|
||||
|
||||
uploadFailed(error) {
|
||||
if (isThemeValidationError(error)) {
|
||||
let errors = error.payload.errors[0].errorDetails;
|
||||
let errors = error.payload.errors[0].details;
|
||||
let fatalErrors = [];
|
||||
let normalErrors = [];
|
||||
|
||||
|
@ -146,7 +146,7 @@ export default Controller.extend({
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (isThemeValidationError(error)) {
|
||||
let errors = error.payload.errors[0].errorDetails;
|
||||
let errors = error.payload.errors[0].details;
|
||||
let fatalErrors = [];
|
||||
let normalErrors = [];
|
||||
|
||||
|
@ -29,7 +29,7 @@ export function isVersionMismatchError(errorOrStatus, payload) {
|
||||
if (isAjaxError(errorOrStatus)) {
|
||||
return errorOrStatus instanceof VersionMismatchError;
|
||||
} else {
|
||||
return get(payload || {}, 'errors.firstObject.errorType') === 'VersionMismatchError';
|
||||
return get(payload || {}, 'errors.firstObject.type') === 'VersionMismatchError';
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ export function isThemeValidationError(errorOrStatus, payload) {
|
||||
if (isAjaxError(errorOrStatus)) {
|
||||
return errorOrStatus instanceof ThemeValidationError;
|
||||
} else {
|
||||
return get(payload || {}, 'errors.firstObject.errorType') === 'ThemeValidationError';
|
||||
return get(payload || {}, 'errors.firstObject.type') === 'ThemeValidationError';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ export default function mockAuthentication(server) {
|
||||
errors: [
|
||||
{
|
||||
message: 'There is no user with that email address.',
|
||||
errorType: 'NotFoundError'
|
||||
type: 'NotFoundError'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ export default function mockIntegrations(server) {
|
||||
|
||||
if (!params.name) {
|
||||
return new Response(422, {}, {errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Name is required',
|
||||
property: 'name'
|
||||
}]});
|
||||
@ -22,7 +22,7 @@ export default function mockIntegrations(server) {
|
||||
|
||||
if (integrations.findBy({name: params.name}) || params.name.match(/Duplicate/i)) {
|
||||
return new Response(422, {}, {errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Name has already been used',
|
||||
property: 'name'
|
||||
}]});
|
||||
|
@ -11,7 +11,7 @@ export default function mockInvites(server) {
|
||||
|
||||
return invite || new Response(404, {}, {
|
||||
errors: [{
|
||||
errorType: 'NotFoundError',
|
||||
type: 'NotFoundError',
|
||||
message: 'Invite not found.'
|
||||
}]
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ export default function mockMembers(server) {
|
||||
|
||||
return member || new Response(404, {}, {
|
||||
errors: [{
|
||||
errorType: 'NotFoundError',
|
||||
type: 'NotFoundError',
|
||||
message: 'Member not found.'
|
||||
}]
|
||||
});
|
||||
|
@ -97,7 +97,7 @@ export default function mockPages(server) {
|
||||
|
||||
return page || new Response(404, {}, {
|
||||
errors: [{
|
||||
errorType: 'NotFoundError',
|
||||
type: 'NotFoundError',
|
||||
message: 'Page not found.'
|
||||
}]
|
||||
});
|
||||
|
@ -97,7 +97,7 @@ export default function mockPosts(server) {
|
||||
|
||||
return post || new Response(404, {}, {
|
||||
errors: [{
|
||||
errorType: 'NotFoundError',
|
||||
type: 'NotFoundError',
|
||||
message: 'Post not found.'
|
||||
}]
|
||||
});
|
||||
|
@ -12,7 +12,7 @@ export default function mockSubscribers(server) {
|
||||
if (subscriber) {
|
||||
return new Response(422, {}, {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Email already exists.',
|
||||
property: 'email'
|
||||
}]
|
||||
|
@ -10,7 +10,7 @@ export default function mockUsers(server) {
|
||||
return user;
|
||||
} else {
|
||||
return new Response(404, {}, {errors: [
|
||||
{message: 'Not found', errorType: 'NotFoundError'}
|
||||
{message: 'Not found', type: 'NotFoundError'}
|
||||
]});
|
||||
}
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ export default function mockWebhooks(server) {
|
||||
|
||||
if (!attrs.name) {
|
||||
errors.push({
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Name is required',
|
||||
property: 'name'
|
||||
});
|
||||
@ -19,7 +19,7 @@ export default function mockWebhooks(server) {
|
||||
|
||||
if (!attrs.event) {
|
||||
errors.push({
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Event is required',
|
||||
property: 'event'
|
||||
});
|
||||
@ -27,7 +27,7 @@ export default function mockWebhooks(server) {
|
||||
|
||||
if (!attrs.targetUrl) {
|
||||
errors.push({
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Target URL is required',
|
||||
property: 'target_url'
|
||||
});
|
||||
@ -35,7 +35,7 @@ export default function mockWebhooks(server) {
|
||||
|
||||
if (attrs.name && (webhooks.findBy({name: attrs.name, integrationId: attrs.integrationId}) || attrs.name.match(/Duplicate/i))) {
|
||||
errors.push({
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Name has already been used',
|
||||
property: 'name'
|
||||
});
|
||||
@ -44,7 +44,7 @@ export default function mockWebhooks(server) {
|
||||
// TODO: check server-side validation
|
||||
if (webhooks.findBy({targetUrl: attrs.targetUrl, event: attrs.event})) {
|
||||
errors.push({
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Target URL has already been used for this event',
|
||||
property: 'target_url'
|
||||
});
|
||||
|
@ -59,7 +59,7 @@ export function paginateModelCollection(modelName, collection, page, limit) {
|
||||
export function maintenanceResponse() {
|
||||
return new Response(503, {}, {
|
||||
errors: [{
|
||||
errorType: 'Maintenance'
|
||||
type: 'Maintenance'
|
||||
}]
|
||||
});
|
||||
}
|
||||
@ -67,7 +67,7 @@ export function maintenanceResponse() {
|
||||
export function versionMismatchResponse() {
|
||||
return new Response(400, {}, {
|
||||
errors: [{
|
||||
errorType: 'VersionMismatchError'
|
||||
type: 'VersionMismatchError'
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ describe('Acceptance: Authentication', function () {
|
||||
// return a 401 when attempting to retrieve users
|
||||
this.server.get('/users/', () => new Response(401, {}, {
|
||||
errors: [
|
||||
{message: 'Access denied.', errorType: 'UnauthorizedError'}
|
||||
{message: 'Access denied.', type: 'UnauthorizedError'}
|
||||
]
|
||||
}));
|
||||
|
||||
@ -116,7 +116,7 @@ describe('Acceptance: Authentication', function () {
|
||||
if (attrs.mobiledoc.cards[0][1].markdown === 'Edited post body') {
|
||||
return new Response(401, {}, {
|
||||
errors: [
|
||||
{message: 'Access denied.', errorType: 'UnauthorizedError'}
|
||||
{message: 'Access denied.', type: 'UnauthorizedError'}
|
||||
]
|
||||
});
|
||||
} else {
|
||||
|
@ -427,7 +427,7 @@ describe('Acceptance: Editor', function () {
|
||||
this.server.put('/posts/:id/', function () {
|
||||
return new Mirage.Response(422, {}, {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Error test'
|
||||
}]
|
||||
});
|
||||
|
@ -293,8 +293,8 @@ describe('Acceptance: Settings - Design', function () {
|
||||
errors: [
|
||||
{
|
||||
message: 'Theme is not compatible or contains errors.',
|
||||
errorType: 'ThemeValidationError',
|
||||
errorDetails: [
|
||||
type: 'ThemeValidationError',
|
||||
details: [
|
||||
{
|
||||
level: 'error',
|
||||
rule: 'Assets such as CSS & JS must use the <code>{{asset}}</code> helper',
|
||||
@ -491,8 +491,8 @@ describe('Acceptance: Settings - Design', function () {
|
||||
errors: [
|
||||
{
|
||||
message: 'Theme is not compatible or contains errors.',
|
||||
errorType: 'ThemeValidationError',
|
||||
errorDetails: [
|
||||
type: 'ThemeValidationError',
|
||||
details: [
|
||||
{
|
||||
level: 'error',
|
||||
rule: 'Assets such as CSS & JS must use the <code>{{asset}}</code> helper',
|
||||
|
@ -133,7 +133,7 @@ describe('Acceptance: Settings - General', function () {
|
||||
this.server.post('/images/upload/', function () {
|
||||
return {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Wrong icon size'
|
||||
}]
|
||||
};
|
||||
@ -202,7 +202,7 @@ describe('Acceptance: Settings - General', function () {
|
||||
this.server.post('/images/upload/', function () {
|
||||
return {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Wrong logo size'
|
||||
}]
|
||||
};
|
||||
@ -271,7 +271,7 @@ describe('Acceptance: Settings - General', function () {
|
||||
this.server.post('/images/upload/', function () {
|
||||
return {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Wrong coverImage size'
|
||||
}]
|
||||
};
|
||||
|
@ -125,7 +125,7 @@ describe('Acceptance: Settings - Labs', function () {
|
||||
// failed upload
|
||||
this.server.post('/redirects/json/', {
|
||||
errors: [{
|
||||
errorType: 'BadRequestError',
|
||||
type: 'BadRequestError',
|
||||
message: 'Test failure message'
|
||||
}]
|
||||
}, 400);
|
||||
@ -238,7 +238,7 @@ describe('Acceptance: Settings - Labs', function () {
|
||||
// failed upload
|
||||
this.server.post('/settings/routes/yaml/', {
|
||||
errors: [{
|
||||
errorType: 'BadRequestError',
|
||||
type: 'BadRequestError',
|
||||
message: 'Test failure message'
|
||||
}]
|
||||
}, 400);
|
||||
|
@ -98,7 +98,7 @@ describe('Acceptance: Settings - Integrations - Slack', function () {
|
||||
return new Mirage.Response(422, {}, {
|
||||
errors: [
|
||||
{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Test error'
|
||||
}
|
||||
]
|
||||
|
@ -309,7 +309,7 @@ describe('Acceptance: Settings - Tags', function () {
|
||||
|
||||
it('redirects to 404 when tag does not exist', async function () {
|
||||
this.server.get('/tags/slug/unknown/', function () {
|
||||
return new Response(404, {'Content-Type': 'application/json'}, {errors: [{message: 'Tag not found.', errorType: 'NotFoundError'}]});
|
||||
return new Response(404, {'Content-Type': 'application/json'}, {errors: [{message: 'Tag not found.', type: 'NotFoundError'}]});
|
||||
});
|
||||
|
||||
errorOverride();
|
||||
|
@ -151,7 +151,7 @@ describe('Acceptance: Setup', function () {
|
||||
return new Response(422, {}, {
|
||||
errors: [
|
||||
{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Server response message'
|
||||
}
|
||||
]
|
||||
@ -198,7 +198,7 @@ describe('Acceptance: Setup', function () {
|
||||
return new Response(401, {}, {
|
||||
errors: [
|
||||
{
|
||||
errorType: 'UnauthorizedError',
|
||||
type: 'UnauthorizedError',
|
||||
message: 'Access Denied from url: unknown.com. Please use the url configured in config.js.'
|
||||
}
|
||||
]
|
||||
@ -241,7 +241,7 @@ describe('Acceptance: Setup', function () {
|
||||
return new Response(422, {}, {
|
||||
errors: [
|
||||
{
|
||||
errorType: 'ValidationError',
|
||||
type: 'ValidationError',
|
||||
message: 'Dummy validation error'
|
||||
}
|
||||
]
|
||||
|
@ -43,7 +43,7 @@ describe('Acceptance: Signin', function () {
|
||||
} else {
|
||||
return new Response(401, {}, {
|
||||
errors: [{
|
||||
errorType: 'UnauthorizedError',
|
||||
type: 'UnauthorizedError',
|
||||
message: 'Invalid Password'
|
||||
}]
|
||||
});
|
||||
|
@ -874,7 +874,7 @@ describe('Acceptance: Staff', function () {
|
||||
|
||||
it('redirects to 404 when user does not exist', async function () {
|
||||
this.server.get('/users/slug/unknown/', function () {
|
||||
return new Response(404, {'Content-Type': 'application/json'}, {errors: [{message: 'User not found.', errorType: 'NotFoundError'}]});
|
||||
return new Response(404, {'Content-Type': 'application/json'}, {errors: [{message: 'User not found.', type: 'NotFoundError'}]});
|
||||
});
|
||||
|
||||
errorOverride();
|
||||
@ -898,7 +898,7 @@ describe('Acceptance: Staff', function () {
|
||||
this.server.get('/invites/', function () {
|
||||
return new Response(403, {}, {
|
||||
errors: [{
|
||||
errorType: 'NoPermissionError',
|
||||
type: 'NoPermissionError',
|
||||
message: 'You do not have permission to perform this action'
|
||||
}]
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ const stubFailedUpload = function (server, code, error, delay = 0) {
|
||||
server.post('/ghost/api/v2/admin/images/', function () {
|
||||
return [code, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
errors: [{
|
||||
errorType: error,
|
||||
type: error,
|
||||
message: `Error: ${error}`
|
||||
}]
|
||||
})];
|
||||
|
@ -38,7 +38,7 @@ const stubFailedUpload = function (server, code, error, delay = 0) {
|
||||
server.post('/ghost/api/v2/admin/images/upload/', function () {
|
||||
return [code, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
errors: [{
|
||||
errorType: error,
|
||||
type: error,
|
||||
message: `Error: ${error}`
|
||||
}]
|
||||
})];
|
||||
|
@ -17,7 +17,7 @@ const stubFailedUpload = function (server, code, error, delay = 0) {
|
||||
server.post('/ghost/api/v2/admin/images/upload/', function () {
|
||||
return [code, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
errors: [{
|
||||
errorType: error,
|
||||
type: error,
|
||||
message: `Error: ${error}`
|
||||
}]
|
||||
})];
|
||||
|
@ -131,7 +131,7 @@ describe('Integration: Service: ajax', function () {
|
||||
{'Content-Type': 'application/json'},
|
||||
JSON.stringify({
|
||||
errors: [{
|
||||
errorType: 'VersionMismatchError',
|
||||
type: 'VersionMismatchError',
|
||||
statusCode: 400
|
||||
}]
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user