improve error handling for 401 requests and fetch

This commit is contained in:
Gregor Vostrak
2024-06-01 00:12:03 +02:00
parent a64ee87d19
commit bae4265f70
13 changed files with 305 additions and 249 deletions

View File

@@ -24,15 +24,16 @@ async function invitePlaceholder(id: string) {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.invitePlaceholder(
{},
{
params: {
organization: organizationId,
member: id,
},
}
),
() =>
api.invitePlaceholder(
{},
{
params: {
organization: organizationId,
member: id,
},
}
),
'Member invited successfully',
'Error inviting member'
);

View File

@@ -10,6 +10,7 @@ import { getCurrentOrganizationId } from '@/utils/useUser';
import type { ImportReport, ImportType } from '@/utils/api';
import DialogModal from '@/Components/DialogModal.vue';
import SecondaryButton from '@/Components/SecondaryButton.vue';
import { initializeStores } from '@/utils/init';
const importTypeOptions = ref<ImportType[]>([]);
const { addNotification } = useNotificationsStore();
@@ -50,19 +51,24 @@ async function importData() {
if (organizationId !== null) {
const { handleApiRequestNotifications } = useNotificationsStore();
reportResult.value = await handleApiRequestNotifications(
api.importData(
{
type: importType.value.key,
data: base64String,
},
{
params: {
organization: organizationId,
reportResult.value = await handleApiRequestNotifications(() => {
if (importType.value) {
return api.importData(
{
type: importType.value.key,
data: base64String,
},
}
)
);
{
params: {
organization: organizationId,
},
}
);
}
return new Promise((resolve, reject) => {
reject('Import type is null');
});
});
if (reportResult.value) {
showResultModal.value = true;
}

View File

@@ -37,13 +37,23 @@ export const useNotificationsStore = defineStore('notifications', () => {
}
}
async function fetchToken() {
return new Promise((resolve) => {
router.reload({
onFinish: () => {
resolve(null);
},
});
});
}
async function handleApiRequestNotifications<T>(
apiRequest: Promise<T>,
apiRequest: () => Promise<T>,
successMessage?: string,
errorMessage?: string
) {
try {
const response = await apiRequest;
const response = await apiRequest();
if (successMessage) {
addNotification('success', successMessage);
}
@@ -65,7 +75,16 @@ export const useNotificationsStore = defineStore('notifications', () => {
const message = error.response.data.message;
addNotification('error', message);
} else if (error?.response?.status === 401) {
router.get(route('login'));
await fetchToken();
try {
const response = await apiRequest();
if (successMessage) {
addNotification('success', successMessage);
}
return response;
} catch (error) {
router.get(route('login'));
}
} else {
addNotification(
'error',

View File

@@ -17,11 +17,12 @@ export const useClientsStore = defineStore('clients', () => {
const organization = getCurrentOrganizationId();
if (organization) {
clientResponse.value = await handleApiRequestNotifications(
api.getClients({
params: {
organization: organization,
},
}),
() =>
api.getClients({
params: {
organization: organization,
},
}),
undefined,
'Failed to fetch clients'
);
@@ -34,11 +35,12 @@ export const useClientsStore = defineStore('clients', () => {
const organization = getCurrentOrganizationId();
if (organization) {
const response = await handleApiRequestNotifications(
api.createClient(clientBody, {
params: {
organization: organization,
},
}),
() =>
api.createClient(clientBody, {
params: {
organization: organization,
},
}),
'Client created successfully',
'Failed to create client'
);
@@ -51,15 +53,16 @@ export const useClientsStore = defineStore('clients', () => {
const organization = getCurrentOrganizationId();
if (organization) {
await handleApiRequestNotifications(
api.deleteClient(
{},
{
params: {
organization: organization,
client: clientId,
},
}
),
() =>
api.deleteClient(
{},
{
params: {
organization: organization,
client: clientId,
},
}
),
'Client deleted successfully',
'Failed to delete client'
);

View File

@@ -89,18 +89,19 @@ export const useCurrentTimeEntryStore = defineStore('currentTimeEntry', () => {
? currentTimeEntry.value.start
: dayjs().utc().format();
const response = await handleApiRequestNotifications(
api.createTimeEntry(
{
member_id: membership,
start: startTime,
description: currentTimeEntry.value?.description,
project_id: currentTimeEntry.value?.project_id,
task_id: currentTimeEntry.value?.task_id,
billable: currentTimeEntry.value.billable,
tags: currentTimeEntry.value?.tags,
},
{ params: { organization: organization } }
),
() =>
api.createTimeEntry(
{
member_id: membership,
start: startTime,
description: currentTimeEntry.value?.description,
project_id: currentTimeEntry.value?.project_id,
task_id: currentTimeEntry.value?.task_id,
billable: currentTimeEntry.value.billable,
tags: currentTimeEntry.value?.tags,
},
{ params: { organization: organization } }
),
'Timer started!'
);
if (response?.data) {
@@ -119,19 +120,20 @@ export const useCurrentTimeEntryStore = defineStore('currentTimeEntry', () => {
if (organization) {
const currentDateTime = dayjs().utc().format();
await handleApiRequestNotifications(
api.updateTimeEntry(
{
user_id: user,
start: currentTimeEntry.value.start,
end: currentDateTime,
},
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
() =>
api.updateTimeEntry(
{
user_id: user,
start: currentTimeEntry.value.start,
end: currentDateTime,
},
}
),
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
},
}
),
'Timer stopped!'
);
$reset();
@@ -147,24 +149,25 @@ export const useCurrentTimeEntryStore = defineStore('currentTimeEntry', () => {
const organization = getCurrentOrganizationId();
if (organization) {
const response = await handleApiRequestNotifications(
api.updateTimeEntry(
{
description: currentTimeEntry.value.description,
user_id: user,
project_id: currentTimeEntry.value.project_id,
task_id: currentTimeEntry.value.task_id,
start: currentTimeEntry.value.start,
billable: currentTimeEntry.value.billable,
end: null,
tags: currentTimeEntry.value.tags,
},
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
() =>
api.updateTimeEntry(
{
description: currentTimeEntry.value.description,
user_id: user,
project_id: currentTimeEntry.value.project_id,
task_id: currentTimeEntry.value.task_id,
start: currentTimeEntry.value.start,
billable: currentTimeEntry.value.billable,
end: null,
tags: currentTimeEntry.value.tags,
},
}
),
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
},
}
),
'Time entry updated!'
);
if (response?.data) {

View File

@@ -17,11 +17,12 @@ export const useInvitationsStore = defineStore('invitations', () => {
const organization = getCurrentOrganizationId();
if (organization) {
invitationsResponse.value = await handleApiRequestNotifications(
api.getInvitations({
params: {
organization: organization,
},
}),
() =>
api.getInvitations({
params: {
organization: organization,
},
}),
undefined,
'Failed to fetch invitations'
);
@@ -34,11 +35,12 @@ export const useInvitationsStore = defineStore('invitations', () => {
const organization = getCurrentOrganizationId();
if (organization) {
await handleApiRequestNotifications(
api.invite(inviteBody, {
params: {
organization: organization,
},
}),
() =>
api.invite(inviteBody, {
params: {
organization: organization,
},
}),
'User successfully invited',
'Failed to invite user'
);

View File

@@ -13,11 +13,12 @@ export const useMembersStore = defineStore('members', () => {
const organization = getCurrentOrganizationId();
if (organization) {
membersResponse.value = await handleApiRequestNotifications(
api.getMembers({
params: {
organization: organization,
},
}),
() =>
api.getMembers({
params: {
organization: organization,
},
}),
undefined,
'Failed to fetch members'
);
@@ -28,15 +29,16 @@ export const useMembersStore = defineStore('members', () => {
const organization = getCurrentOrganizationId();
if (organization) {
await handleApiRequestNotifications(
api.removeMember(
{},
{
params: {
organization: organization,
member: membershipId,
},
}
),
() =>
api.removeMember(
{},
{
params: {
organization: organization,
member: membershipId,
},
}
),
'Member deleted successfully',
'Failed to delete member'
);

View File

@@ -17,12 +17,13 @@ export const useProjectMembersStore = defineStore('project-members', () => {
const organization = getCurrentOrganizationId();
if (organization) {
projectMemberResponse.value = await handleApiRequestNotifications(
api.getProjectMembers({
params: {
organization: organization,
project: projectId,
},
}),
() =>
api.getProjectMembers({
params: {
organization: organization,
project: projectId,
},
}),
undefined,
'Failed to fetch project members'
);
@@ -36,12 +37,13 @@ export const useProjectMembersStore = defineStore('project-members', () => {
const organization = getCurrentOrganizationId();
if (organization) {
await handleApiRequestNotifications(
api.createProjectMember(projectMemberBody, {
params: {
organization: organization,
project: projectId,
},
}),
() =>
api.createProjectMember(projectMemberBody, {
params: {
organization: organization,
project: projectId,
},
}),
'Project member added successfully',
'Failed to add project member'
);
@@ -56,15 +58,16 @@ export const useProjectMembersStore = defineStore('project-members', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.deleteProjectMember(
{},
{
params: {
organization: organizationId,
projectMember: projectMemberId,
},
}
),
() =>
api.deleteProjectMember(
{},
{
params: {
organization: organizationId,
projectMember: projectMemberId,
},
}
),
'Project member removed successfully',
'Failed to remove project member'
);

View File

@@ -17,11 +17,12 @@ export const useProjectsStore = defineStore('projects', () => {
const organization = getCurrentOrganizationId();
if (organization) {
projectResponse.value = await handleApiRequestNotifications(
api.getProjects({
params: {
organization: organization,
},
}),
() =>
api.getProjects({
params: {
organization: organization,
},
}),
undefined,
'Failed to fetch projects'
);
@@ -32,11 +33,12 @@ export const useProjectsStore = defineStore('projects', () => {
const organization = getCurrentOrganizationId();
if (organization) {
await handleApiRequestNotifications(
api.createProject(projectBody, {
params: {
organization: organization,
},
}),
() =>
api.createProject(projectBody, {
params: {
organization: organization,
},
}),
'Project created successfully',
'Failed to create project'
);
@@ -49,15 +51,16 @@ export const useProjectsStore = defineStore('projects', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.deleteProject(
{},
{
params: {
organization: organizationId,
project: projectId,
},
}
),
() =>
api.deleteProject(
{},
{
params: {
organization: organizationId,
project: projectId,
},
}
),
'Project deleted successfully',
'Failed to delete project'
);
@@ -72,12 +75,13 @@ export const useProjectsStore = defineStore('projects', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.updateProject(updateProjectBody, {
params: {
organization: organizationId,
project: projectId,
},
}),
() =>
api.updateProject(updateProjectBody, {
params: {
organization: organizationId,
project: projectId,
},
}),
'Project updated successfully',
'Failed to update project'
);

View File

@@ -39,12 +39,13 @@ export const useReportingStore = defineStore('reporting', () => {
const organization = getCurrentOrganizationId();
if (organization) {
reportingGraphResponse.value = await handleApiRequestNotifications(
api.getAggregatedTimeEntries({
params: {
organization: organization,
},
queries: params,
}),
() =>
api.getAggregatedTimeEntries({
params: {
organization: organization,
},
queries: params,
}),
undefined,
'Failed to fetch reporting data'
);
@@ -57,12 +58,13 @@ export const useReportingStore = defineStore('reporting', () => {
const organization = getCurrentOrganizationId();
if (organization) {
reportingTableResponse.value = await handleApiRequestNotifications(
api.getAggregatedTimeEntries({
params: {
organization: organization,
},
queries: params,
}),
() =>
api.getAggregatedTimeEntries({
params: {
organization: organization,
},
queries: params,
}),
undefined,
'Failed to fetch reporting data'
);

View File

@@ -12,11 +12,12 @@ export const useTagsStore = defineStore('tags', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
const response = await handleApiRequestNotifications(
api.getTags({
params: {
organization: organizationId,
},
}),
() =>
api.getTags({
params: {
organization: organizationId,
},
}),
undefined,
'Failed to fetch tags'
);
@@ -34,15 +35,16 @@ export const useTagsStore = defineStore('tags', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.deleteTag(
{},
{
params: {
organization: organizationId,
tag: tagId,
},
}
),
() =>
api.deleteTag(
{},
{
params: {
organization: organizationId,
tag: tagId,
},
}
),
'Tag deleted successfully',
'Failed to delete tag'
);
@@ -54,16 +56,17 @@ export const useTagsStore = defineStore('tags', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
const response = await handleApiRequestNotifications(
api.createTag(
{
name: name,
},
{
params: {
organization: organizationId,
() =>
api.createTag(
{
name: name,
},
}
),
{
params: {
organization: organizationId,
},
}
),
'Tag created successfully',
'Failed to create tag'
);

View File

@@ -12,7 +12,7 @@ export const useTasksStore = defineStore('tasks', () => {
async function fetchTasks() {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
const tasksResponse = await handleApiRequestNotifications(
const tasksResponse = await handleApiRequestNotifications(() =>
api.getTasks({
params: {
organization: organizationId,
@@ -29,12 +29,13 @@ export const useTasksStore = defineStore('tasks', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.updateTask(task, {
params: {
organization: organizationId,
task: task.id,
},
}),
() =>
api.updateTask(task, {
params: {
organization: organizationId,
task: task.id,
},
}),
'Task updated successfully',
'Failed to update task'
);
@@ -45,11 +46,12 @@ export const useTasksStore = defineStore('tasks', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.createTask(task, {
params: {
organization: organizationId,
},
}),
() =>
api.createTask(task, {
params: {
organization: organizationId,
},
}),
'Task created successfully',
'Failed to create task'
);
@@ -61,15 +63,16 @@ export const useTasksStore = defineStore('tasks', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.deleteTask(
{},
{
params: {
organization: organizationId,
task: taskId,
},
}
),
() =>
api.deleteTask(
{},
{
params: {
organization: organizationId,
task: taskId,
},
}
),
'Task deleted successfully',
'Failed to delete task'
);

View File

@@ -21,15 +21,16 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
const timeEntriesResponse = await handleApiRequestNotifications(
api.getTimeEntries({
params: {
organization: organizationId,
},
queries: {
only_full_dates: 'true',
member_id: getCurrentMembershipId(),
},
}),
() =>
api.getTimeEntries({
params: {
organization: organizationId,
},
queries: {
only_full_dates: 'true',
member_id: getCurrentMembershipId(),
},
}),
undefined,
'Failed to fetch time entries'
);
@@ -47,16 +48,17 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
dayjs(latestTimeEntry.start).utc().format('YYYY-MM-DD');
const timeEntriesResponse = await handleApiRequestNotifications(
api.getTimeEntries({
params: {
organization: organizationId,
},
queries: {
only_full_dates: 'true',
member_id: getCurrentMembershipId(),
end: dayjs(latestTimeEntry.start).utc().format(),
},
}),
() =>
api.getTimeEntries({
params: {
organization: organizationId,
},
queries: {
only_full_dates: 'true',
member_id: getCurrentMembershipId(),
end: dayjs(latestTimeEntry.start).utc().format(),
},
}),
undefined,
'Failed to fetch time entries'
);
@@ -77,12 +79,13 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.updateTimeEntry(timeEntry, {
params: {
organization: organizationId,
timeEntry: timeEntry.id,
},
}),
() =>
api.updateTimeEntry(timeEntry, {
params: {
organization: organizationId,
timeEntry: timeEntry.id,
},
}),
'Time entry updated successfully',
'Failed to update time entry'
);
@@ -100,11 +103,12 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
member_id: memberId,
} as CreateTimeEntryBody;
await handleApiRequestNotifications(
api.createTimeEntry(newTimeEntry, {
params: {
organization: organizationId,
},
}),
() =>
api.createTimeEntry(newTimeEntry, {
params: {
organization: organizationId,
},
}),
'Time entry created successfully',
'Failed to create time entry'
);
@@ -116,15 +120,16 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
api.deleteTimeEntry(
{},
{
params: {
organization: organizationId,
timeEntry: timeEntryId,
},
}
),
() =>
api.deleteTimeEntry(
{},
{
params: {
organization: organizationId,
timeEntry: timeEntryId,
},
}
),
'Time entry deleted successfully',
'Failed to delete time entry'
);