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(); const organizationId = getCurrentOrganizationId();
if (organizationId) { if (organizationId) {
await handleApiRequestNotifications( await handleApiRequestNotifications(
api.invitePlaceholder( () =>
{}, api.invitePlaceholder(
{ {},
params: { {
organization: organizationId, params: {
member: id, organization: organizationId,
}, member: id,
} },
), }
),
'Member invited successfully', 'Member invited successfully',
'Error inviting member' 'Error inviting member'
); );

View File

@@ -10,6 +10,7 @@ import { getCurrentOrganizationId } from '@/utils/useUser';
import type { ImportReport, ImportType } from '@/utils/api'; import type { ImportReport, ImportType } from '@/utils/api';
import DialogModal from '@/Components/DialogModal.vue'; import DialogModal from '@/Components/DialogModal.vue';
import SecondaryButton from '@/Components/SecondaryButton.vue'; import SecondaryButton from '@/Components/SecondaryButton.vue';
import { initializeStores } from '@/utils/init';
const importTypeOptions = ref<ImportType[]>([]); const importTypeOptions = ref<ImportType[]>([]);
const { addNotification } = useNotificationsStore(); const { addNotification } = useNotificationsStore();
@@ -50,19 +51,24 @@ async function importData() {
if (organizationId !== null) { if (organizationId !== null) {
const { handleApiRequestNotifications } = useNotificationsStore(); const { handleApiRequestNotifications } = useNotificationsStore();
reportResult.value = await handleApiRequestNotifications( reportResult.value = await handleApiRequestNotifications(() => {
api.importData( if (importType.value) {
{ return api.importData(
type: importType.value.key, {
data: base64String, type: importType.value.key,
}, data: base64String,
{
params: {
organization: organizationId,
}, },
} {
) params: {
); organization: organizationId,
},
}
);
}
return new Promise((resolve, reject) => {
reject('Import type is null');
});
});
if (reportResult.value) { if (reportResult.value) {
showResultModal.value = true; 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>( async function handleApiRequestNotifications<T>(
apiRequest: Promise<T>, apiRequest: () => Promise<T>,
successMessage?: string, successMessage?: string,
errorMessage?: string errorMessage?: string
) { ) {
try { try {
const response = await apiRequest; const response = await apiRequest();
if (successMessage) { if (successMessage) {
addNotification('success', successMessage); addNotification('success', successMessage);
} }
@@ -65,7 +75,16 @@ export const useNotificationsStore = defineStore('notifications', () => {
const message = error.response.data.message; const message = error.response.data.message;
addNotification('error', message); addNotification('error', message);
} else if (error?.response?.status === 401) { } 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 { } else {
addNotification( addNotification(
'error', 'error',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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