cheetah-framework
Version:
Cheetah Framework JS used in all our applications
149 lines (133 loc) • 4.01 kB
JavaScript
/* global cheetahApp */
import config from '@cheetah/config'
import RestrictionMessage from '@cheetah/components/RestrictionMessage'
import App from '@cheetah/utils/App'
import axios from 'axios'
window.axios = axios
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
const token = document.head.querySelector('meta[name="csrf-token"]')
window.crsfToken = token
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token')
}
/**
* Add a response interceptor
*
* Response that should stop the promise flow should
* return a never resolving promise. No memory leaks should
* happen since nothing reference the promise, provoking the garbage
* collector to collect the created promise.
*
* For more information, {@see https://stackoverflow.com/questions/36734900/what-happens-if-you-dont-resolve-or-reject-a-promise}
*/
window.axios.interceptors.response.use(null, function (error) {
if (error instanceof window.axios.Cancel) {
throw error
}
if (error.response) {
switch (error.response.status) {
case 422:
const allowForce = _.get(error, 'response.data.allow_force', null)
if (allowForce !== null) {
return new Promise((resolve, reject) => {
let componentInstance = App.create(RestrictionMessage, { error, resolve, reject })
componentInstance.$on('close', _ => {
componentInstance.$destroy() // cleanup in component
componentInstance.$el.innerHTML = '' // remove inner content
componentInstance = null // I drop the reference so it can be GC'd
})
componentInstance.$mount()
})
}
break
case 401:
case 419:
return cheetahApp.$store.dispatch('Auth/fetchUser').then(response => {
if (!response.data.user) {
config.handlers.sessionExpire()
throw new window.axios.Cancel()
} else {
const oldCall = _.omit(error.config, ['headers'])
oldCall.headers = _.omit(error.config.headers, ['X-CSRF-TOKEN'])
return axios(oldCall)
}
})
// no default
}
}
throw error
})
/**
* FALLBACK ERROR
* That error cannot be intercept because of missing
* allow_force param. Can be use in RemoteError class
* of any Form components.
*
* error.response.data = {
* message: 'Error message', // Use as popup title
* errors: {
* // Standard laravel errors
* }
* }
*/
/** *****************************
* EXAMPLES OF BACKEND ERROR
* VALID FOR THE INTERCEPTOR
*/
/**
* Warning messages with a force option
*
* error.response.data = {
* message: 'Warning message', // Use as popup title
* allow_force: 1, // force level we need to return (>= 1)
* warnings: [
* // list of warning to display to the user (text only)
* ]
* }
*/
/**
* Warning messages WITHOUT force option
* Similar to fallback error
*
* error.response.data = {
* message: 'Warning message', // Use as popup title
* allow_force: 0, // cant be forced
* warnings: [
* // list of warning to display to the user (text only)
* ]
* }
*/
/**
* Error message with linkable resources
* and force option
*
* error.response.data = {
* message: 'Warning message', // Use as popup title
* allow_force: 1, // force level we need to return (>= 1)
* restrictions: {
* 'laravel_resource_name': {
* 1: 'soft_restrict',
* 2: 'soft_restrict',
* 3: 'soft_restrict'
* }
* }
* }
*/
/**
* Error message with linkable resources
* WITHOUT force option
*
* error.response.data = {
* message: 'Error message', // Use as popup title
* allow_force: 0, // cant be forced
* restrictions: {
* 'laravel_resource_name': {
* 1: 'restrict',
* 2: 'soft_restrict',
* 3: 'restrict'
* }
* }
* }
*/