Permalink
Browse files

feat(axios): redirectError

  • Loading branch information...
pi0 committed Jul 24, 2017
1 parent f658db3 commit 4ce1a1cef68eafc7d6d5ccad5f13f14a79e8b70c
Showing with 42 additions and 32 deletions.
  1. +14 −8 modules/axios/README.md
  2. +1 −1 modules/axios/index.js
  3. +27 −23 modules/axios/plugin.js
@@ -7,7 +7,7 @@
- Automatically set base URL for client & server side
- Injects `$get`,`$post`,... into vue context instances so requests can be done easily.
- Exposes `setToken` function to `$axios` so we can easily and globally set authentication tokens.
- Throws *nuxt-friendly* exceptions and prevent SSR crashes.
- Throws *nuxt-friendly* errors and optionally redirect on specific error codes.
- Automatically enables `withCredentials` when requesting to base URL.
- Proxy request headers in SSR.

@@ -136,14 +136,20 @@ In SSR context, sets client request header as axios default request headers.
This is useful for making requests which need cookie based auth on server side.
Also helps making consistent requests in both SSR and Client Side code.
### `handleErrors`
- Default: `true`
Adds an interceptor which will `statusCode` and `message` keys to the `error` object
and redirects 401 statuses to `/login`. In SSR context the handler will not reject the promise
and therefore you cannot add your own interceptors. In those circumstances, or if you do not want
this default behaviour, you can set this to `false` to disable this interceptor.
### `redirectError`
- Default: `{}`
This option is a map from specific error codes to page which they should be redirect.
For example if you want redirecting all `401` errors to `/login` use:
```js
{
axios: {
redirectError: {
401: '/login'
}
}
}
```
## Helpers
### `setHeader(name, value, scopes='common')`
@@ -17,7 +17,7 @@ module.exports = function nuxtAxios (moduleOptions) {
credentials: true,
proxyHeaders: true,
debug: false,
handleErrors: true
redirectError: {}
}

const options = Object.assign({}, defaults, this.options.axios, moduleOptions)
@@ -70,12 +70,15 @@ function setToken (token, type, scopes = 'common') {
this.setHeader('Authorization', value, scopes)
}

// Nuxt friendly error handler
const redirectError = <%= serialize(options.redirectError) %>

// Set appreciate `statusCode` and `message` to error instance
function errorHandler(error) {
if (error.response) {
// Error from backend (non 2xx status code)
if (error.response.status === 401) {
return this.redirect('/login')
// ...Auto redirect on special status codes
if (redirectError[error.response.status]) {
this.redirect(redirectError[error.response.status])
}
error.statusCode = error.statusCode || parseInt(error.response.status) || 500
error.message = error.message || error.response.statusText || (error.statusCode + ' (Internal Server Error)')
@@ -88,18 +91,11 @@ function errorHandler(error) {
error.statusCode = 500
error.message = error.message || 'axios error'
}
// Display error page on unhandled promises
if(process.browser) {
return Promise.reject(error)
} else {
// Don't throw unhandled promises in SSR context
return this.app._nuxt.error.call({$options: this.app}, {
message: error.message,
statusCode: error.statusCode
})
}

return Promise.reject(error)
}

<% if(options.debug) { %>
function debug(level, messages) {
if (!(console[level] instanceof Function)) {
level = 'info'
@@ -117,19 +113,28 @@ function debug(level, messages) {
}
}
}
<% } %>

// Setup BaseURL
const baseURL = process.browser
? (process.env.API_URL_BROWSER || '<%= options.browserBaseURL %>')
: (process.env.API_URL || '<%= options.baseURL %>')

export default (ctx) => {
const { app, store, req } = ctx

// Create new axios instance
const baseURL = process.browser
? (process.env.API_URL_BROWSER || '<%= options.browserBaseURL %>')
: (process.env.API_URL || '<%= options.baseURL %>')
<% if(options.proxyHeaders) { %>
// Default headers
const defaultHeaders = (req && req.headers) ? Object.assign({}, req.headers) : {}
delete defaultHeaders.host
<% } %>

// Create new axios instance
const axios = Axios.create({
baseURL,
<% if(options.proxyHeaders) { %>headers: (req && req.headers) ? Object.assign({}, req.headers, {host: ''}) : {} <% } %>
<% if(options.proxyHeaders) { %>defaultHeaders,<% } %>
})

<% if(options.credentials) { %>
// Send credentials only to relative and API Backend requests
axios.interceptors.request.use(config => {
@@ -143,6 +148,7 @@ export default (ctx) => {
<% } %>

<% if(options.debug) { %>
// Debug
axios.interceptors.request.use(config => {
debug('[@nuxtjs/axios] Request:', config)
return config
@@ -160,18 +166,16 @@ export default (ctx) => {
<% } %>

// Error handler
<% if(options.handleErrors) { %>
axios.interceptors.response.use(undefined, errorHandler.bind(ctx));
<% } %>
axios.interceptors.response.use(undefined, errorHandler.bind(ctx));

// Make accessible using *.$axios
app.$axios = axios
ctx.$axios = axios
if(store) {
if (store) {
store.$axios = axios
}

// token helper for authentication
// Token helper for authentication
axios.setToken = setToken.bind(axios)
axios.setHeader = setHeader.bind(axios)
}

0 comments on commit 4ce1a1c

Please sign in to comment.