Skip to content
Snippets Groups Projects
Commit e9dbd6b4 authored by Dominik Seeger's avatar Dominik Seeger
Browse files

added interceptor to consistently forward errors to the user

parent 80b7c26a
No related branches found
No related tags found
1 merge request!158Resolve "Consistent error handling in frontend"
Pipeline #93516 passed
import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { errorInterceptor } from '@/util/interceptor'
import { Credentials } from '@/store/modules/authentication'
import {
Assignment,
......@@ -233,4 +234,6 @@ export async function fetchInstanceExportData (): Promise<InstanceExportData> {
return (await ax.get('/api/instance/export')).data
}
ax.interceptors.response.use(undefined, errorInterceptor);
export default ax
......@@ -135,6 +135,10 @@ export default {
SubmissionNotes.SET_ORIG_FEEDBACK(feedback)
this.$emit('feedbackCreated')
}).catch(err => {
// ignore trivial errors as those are handled
// by an interceptor
if (err.message.includes("Request failed")) return
this.$notify({
title: 'Feedback creation Error!',
text: err.message,
......
import { AxiosError } from 'axios'
import { AxiosError, AxiosResponse } from 'axios'
import { Dispatch } from 'vuex'
import { MutationHandler } from 'vuex-typex'
......@@ -139,3 +139,35 @@ export function syntaxPostProcess (code: string): string {
})
return code
}
export function parseBlacklist (blacklist: Array<string>): string {
return blacklist.reduce((acc, curr) => {
return acc + "|" + curr
})
}
export function parseErrorNotification (response: AxiosResponse): string {
if (!response.data || Object.keys(response.data).length === 0) {
return 'There is no useful error data. Please ask the staff for help.'
} else {
let msg = "<ul>";
function pickRecursive(obj: any) {
if (obj instanceof Object) {
for (let k of Object.keys(obj)) {
pickRecursive(obj[k])
}
} else {
msg += "<li>" + obj + "</li>"
}
}
pickRecursive(response.data)
msg += "</ul>"
if (response.status === 404) {
msg += "<br/>If you experience unusual behaviour, finish all unfinished work and relog." +
" If not, this is probably not a critical error."
}
return msg
}
}
import instance from '@/main'
import { parseErrorNotification, parseBlacklist } from '@/util/helpers'
const errorUrlBlacklist = [
"/api/get-token/",
]
const blackListRegExp = new RegExp(parseBlacklist(errorUrlBlacklist), "g")
export function errorInterceptor (error: any): any {
// TODO: log errors and store them somewhere
if (error.response.request.responseURL.match(blackListRegExp)) {
return
}
instance.$notify({
title: 'Request failed.',
text: parseErrorNotification(error.response),
type: 'error',
duration: -1
})
return Promise.reject(error)
}
\ No newline at end of file
import * as helpers from "@/util/helpers"
import * as chai from "chai"
import { AxiosResponse } from 'axios';
chai.should();
describe("# Helpers Unit Tests", () => {
describe("# praseBlacklist", () => {
it("should correclty parse the blacklist object into a string that can be used for regex", () => {
const blacklist = ["test", "another", "final"]
const parsed = helpers.parseBlacklist(blacklist)
const testUrl = "https:somehost:someport/api/feedback/final"
const isMatched = testUrl.match(new RegExp(parsed, "g"))
// @ts-ignore
isMatched.should.not.be.null
parsed.should.equal("test|another|final")
})
})
describe("# parseErrorNotification", () => {
it("should return html parsed information about the error if existing", () => {
const response = { data: { someKey: "this is an error message" } }
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
parsed.should.equal("<ul><li>this is an error message</li></ul>")
})
it("should return html parsed list of all values of data object if existing", () => {
const response = {
data: {
someKey: "some debug information",
someOtherKey: "some error information",
someFinalKey: "some response stuff"
}
}
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
const expected = "<ul><li>some debug information</li><li>some error information</li>" +
"<li>some response stuff</li></ul>"
parsed.should.equal(expected)
})
it("should return default message when no error information exists", () => {
const response = { data: {}, someKey: "test" }
const parsed = helpers.parseErrorNotification(response as unknown as AxiosResponse)
parsed.should.equal("There is no useful error data. Please ask the staff for help.")
})
it("should give additional information for 404 requests", () => {
const response = { status: 404, data: { someKey: "Not found." } }
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
parsed.should.include("Not found.")
parsed.should.include("If you experience unusual behaviour, finish all unfinished work and relog." +
" If not, this is probably not a critical error.")
})
})
})
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment