Xinjiang Shao
Software Engineer at Peapod Digital Labs
Xinjiang Shao
10/19/2022
Key aspects of the pattern are that the change is transparent and used automatically. In essence, the rest of the system does not have to know something has been added or changed and can keep working as before.
https://en.wikipedia.org/wiki/Interceptor_pattern
- Interceptor Chain for Requests and Responses
- PR Single Session Support
SESSION_EXPIRED SESSION_LOCKED LOGIN_REQUIRED
https://bitbucket.peapod.com/projects/PEAP/repos/peapod-client/pull-requests/4156/overview
Read the interceptor tests for seeing all this in code.
// instanceof Error
{
config: {},
request: {}
response: {
data:{},
headers: {},
status: 400,
statusText: ""
},
message: ""
}
{
// `data` is the response that was provided by the server
data: {},
// `status` is the HTTP status code from the server response
status: 200,
// `statusText` is the HTTP status message from the server response
// As of HTTP/2 status text is blank or unsupported.
// (HTTP/2 RFC: https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2.4)
statusText: 'OK',
// `headers` the HTTP headers that the server responded with
// All header names are lower cased and can be accessed using the bracket notation.
// Example: `response.headers['content-type']`
headers: {},
// `config` is the config that was provided to `axios` for the request
config: {},
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance in the browser
request: {}
}
// OrderAdjustmentsAPI
import ApiService from '@/api'
put(payload) {
return ApiService.put(`/api/v5.0/user/${payload.userId}/order/${payload.basketId}/adjustments/${payload.field}`, payload.params)
}
// CartPaymentInformation Vuex Store
try {
let promoCodeEffect
promoCodeEffect = await OrderAdjustmentsAPI.put(payload)
// The fallback approach
if (promoCodeEffect?.response) {
promoCodeEffect = promoCodeEffect.response
}
if (promoCodeEffect.status !== 200 || promoCodeEffect.data.response.code !== 'PROMO_CODE_UPDATED') {
const responseCode = safeAccess(() => promoCodeEffect.data.response.code, 'PROMO_CODE_UNKNOWN_ERROR')
throw new Error(responseCode)
}
} catch(e) {
// throw site alert on unknown error
if (e.message === 'PROMO_CODE_UNKNOWN_ERROR') {
setCheckoutAlert(commit, { msg: 'There was an error updating the promo code.' })
}
}
// api/index.js
import axios from 'axios'
const http = axios.create()
export default {
getInstance() {
return http
},
// current method
async put(url, data, config) {
try {
const response = await http.put(url, data, config)
return response
} catch (error) {
return error
}
},
// alternative option for PUT
async corePut(url, data, config) {
const response = await http.put(url, data, config)
return response
},
}
// OrderAdjustmentsAPI
import ApiService from '@/api'
put(payload) {
return ApiService.corePut(`/api/v5.0/user/${payload.userId}/order/${payload.basketId}/adjustments/${payload.field}`, payload.params)
}
// CartPaymentInformation Vuex Store
try {
const result = await OrderAdjustmentsAPI.put(payload)
if (result.status >= 200 && result.status < 400) {
// Mostly likely to reach here
}
if (result.status !== 200) {
// It is unlikely to reach here if we use corePut without swollaw errors
}
} catch(error) {
// throw site alert on unknown error
if (error.response.status >= 400 && error.response.status <= 500) {
// Set current error code with e.g. error.response.data.response.code = 'PROMO_CODE_INVALID_BUS_RULE'
}
}
By Xinjiang Shao