Skip to content
Snippets Groups Projects
Commit 29fc042f authored by VIktorGrev's avatar VIktorGrev
Browse files

feat: Adding global error handling

parent ffc68853
No related branches found
No related tags found
1 merge request!87Global error catcher
Pipeline #283713 failed
......@@ -157,6 +157,7 @@ import { useRouter, useRoute } from "vue-router";
import { useUserInfoStore } from '@/stores/UserStore';
import {onMounted, ref} from "vue";
import { BadgeService, type NotificationDTO, NotificationService } from '@/api'
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const router = useRouter();
const route = useRoute();
......@@ -207,6 +208,7 @@ const getNotifications = async () => {
await BadgeService.updateUnlockedBadges();
notificationListRef.value = await NotificationService.getUnreadNotificationByUser()
} catch (error) {
handleUnknownError(error);
notificationListRef.value = []
}
}
......@@ -217,6 +219,7 @@ const readNotification = async (notification: NotificationDTO) => {
await NotificationService.updateNotification({requestBody: notification});
notificationListRef.value = await NotificationService.getUnreadNotificationByUser()
} catch (error) {
handleUnknownError(error);
notificationListRef.value = [];
}
}
......
<script setup lang="ts">
import { BudgetService } from '@/api'
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const emit = defineEmits(['errorEvent', 'deletedEvent'])
const props = defineProps({
......@@ -25,6 +26,7 @@ const deleteBudget = async () => {
await BudgetService.deleteBudget({budgetId: props.budgetId})
emit('deletedEvent')
} catch (error) {
handleUnknownError(error);
emit('errorEvent', error)
}
}
......
......@@ -4,6 +4,7 @@ import { ref } from 'vue'
import BaseButton from '@/components/BaseComponents/Buttons/BaseButton.vue'
import { useRouter } from 'vue-router'
import {type CreateGoalDTO, GoalService} from "@/api";
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const router = useRouter();
const emit = defineEmits(['changeRouterEvent'])
......@@ -35,6 +36,7 @@ const handleSubmit = async () => {
await GoalService.createGoal({ requestBody: createGoalPayload });
await router.push("/")
} catch (error: any) {
handleUnknownError(error);
console.log(error.message);
errorMessage.value = error.message;
}
......
......@@ -124,6 +124,7 @@ import { type Ref, ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { FriendService, UserService } from '@/api';
import type { UserDTO } from '@/api';
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const router = useRouter();
const friends = ref();
......@@ -155,6 +156,7 @@ const searchProfile = async (searchTerm: string) => {
searchedUsers.value = response;
console.log(response);
} catch (error) {
handleUnknownError(error);
console.error('Failed to search for profile', error);
}
};
......@@ -169,6 +171,7 @@ const addNewFriends = async () => {
searchedUsers.value = response;
showAddFriend.value = true;
} catch (error) {
handleUnknownError(error);
console.error('Failed to add friend', error);
}
};
......@@ -179,6 +182,7 @@ async function addFriend(friendID: number) {
// Use a spread to update the state and keep immutability
friendRequestsSent.value = { ...friendRequestsSent.value, [friendID]: true };
} catch (error) {
handleUnknownError(error);
console.error('Failed to send friend request', error);
}
}
......@@ -192,6 +196,7 @@ async function requestFriend() {
elementsInFriendRequest.value = response.length > 0;
console.log("Friend requests: " + response);
} catch (error) {
handleUnknownError(error);
console.error('Failed to fetch friend requests', error);
}
}
......@@ -206,6 +211,7 @@ const removeFriend = async (friendID: number) => {
const responseFriends = await FriendService.getFriends();
friends.value = responseFriends;
} catch (error) {
handleUnknownError(error);
console.error('Failed to remove friend', error);
}
};
......@@ -219,6 +225,7 @@ const setupFriends = async () => {
elementsInFriends.value = response.length > 0;
console.log(response);
} catch (error) {
handleUnknownError(error);
console.error('Failed to fetch friends', error);
}
};
......@@ -231,6 +238,7 @@ const acceptRequest = async (requestID: number) => {
const responseFriends = await FriendService.getFriends();
friends.value = responseFriends;
} catch (error) {
handleUnknownError(error);
console.error('Failed to accept friend request', error);
}
};
......@@ -241,6 +249,7 @@ const rejectRequest = async (requestID: number) => {
const response = await FriendService.getFriendRequests();
friendRequests.value = response;
} catch (error) {
handleUnknownError(error);
console.error('Failed to reject friend request', error);
}
};
......
......@@ -46,6 +46,7 @@
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import Leaderboard from '@/components/Leaderboard/LeaderboardTable.vue';
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
import { LeaderboardService } from '@/api';
let streakLeaderboardData = ref([] as any);
......@@ -72,44 +73,49 @@ onMounted(() => {
});
async function global() {
let globalPoints = await LeaderboardService.getLeaderboard({
type: "TOTAL_POINTS",
filter: "GLOBAL",
});
let globalStreak = await LeaderboardService.getLeaderboard({
type: "TOP_STREAK",
filter: "GLOBAL",
});
let globalCurrentStreak = await LeaderboardService.getLeaderboard({
type: "CURRENT_STREAK",
filter: "GLOBAL",
});
let globalPointsYou = await LeaderboardService.getSurrounding({
type: "TOTAL_POINTS",
filter: "GLOBAL",
entryCount: 2,
});
let globalStreakYou = await LeaderboardService.getSurrounding({
type: "TOP_STREAK",
filter: "GLOBAL",
entryCount: 2,
});
let globalCurrentStreakYou = await LeaderboardService.getSurrounding({
type: "CURRENT_STREAK",
filter: "GLOBAL",
entryCount: 2,
});
pointsLeaderboardData.value = globalPoints.entries;
currentLeaderboardData.value = globalCurrentStreak.entries;
streakLeaderboardData.value = globalStreak.entries;
pointsLeaderboardDataExtra.value = globalPointsYou.entries;
currentLeaderboardDataExtra.value = globalCurrentStreakYou.entries;
streakLeaderboardDataExtra.value = globalStreakYou.entries;
try {
let globalPoints = await LeaderboardService.getLeaderboard({
type: "TOTAL_POINTS",
filter: "GLOBAL",
});
let globalStreak = await LeaderboardService.getLeaderboard({
type: "TOP_STREAK",
filter: "GLOBAL",
});
let globalCurrentStreak = await LeaderboardService.getLeaderboard({
type: "CURRENT_STREAK",
filter: "GLOBAL",
});
let globalPointsYou = await LeaderboardService.getSurrounding({
type: "TOTAL_POINTS",
filter: "GLOBAL",
entryCount: 2,
});
let globalStreakYou = await LeaderboardService.getSurrounding({
type: "TOP_STREAK",
filter: "GLOBAL",
entryCount: 2,
});
let globalCurrentStreakYou = await LeaderboardService.getSurrounding({
type: "CURRENT_STREAK",
filter: "GLOBAL",
entryCount: 2,
});
pointsLeaderboardData.value = globalPoints.entries;
currentLeaderboardData.value = globalCurrentStreak.entries;
streakLeaderboardData.value = globalStreak.entries;
pointsLeaderboardDataExtra.value = globalPointsYou.entries;
currentLeaderboardDataExtra.value = globalCurrentStreakYou.entries;
streakLeaderboardDataExtra.value = globalStreakYou.entries;
} catch (error) {
handleUnknownError(error);
}
}
async function friends() {
try {
let friendsPoints = await LeaderboardService.getLeaderboard({
type: "TOTAL_POINTS",
filter: "FRIENDS",
......@@ -146,6 +152,9 @@ async function friends() {
pointsLeaderboardDataExtra.value = friendsPointsYou.entries;
currentLeaderboardDataExtra.value = friendsStreakYou.entries;
streakLeaderboardDataExtra.value = friendsCurrentStreakYou.entries;
} catch (error) {
handleUnknownError(error);
}
}
const navigateToUserProfile = (userId: number) => {
......
......@@ -30,6 +30,7 @@
import { ref } from 'vue';
import { UserService } from '@/api';
import BaseButton from '@/components/BaseComponents/Buttons/BaseButton.vue'
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const formRef = ref()
const form = formRef.value;
......@@ -49,6 +50,7 @@
confirmationMessage.value = 'An email has been sent to your email address with a link to reset your password.';
errorMessage.value = '';
} catch (error) {
handleUnknownError(error);
errorMessage.value = 'Failed to send email. Please try again.';
confirmationMessage.value = '';
}
......
......@@ -4,6 +4,7 @@ import BaseInput from '@/components/BaseComponents/Input/BaseInput.vue';
import { useUserInfoStore } from "@/stores/UserStore";
import { UserService } from '@/api';
import type { UserUpdateDTO } from '@/api';
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const emailRef = ref('')
const errorMsg = ref('')
......@@ -22,6 +23,7 @@ async function setupForm() {
confirmationMsg.value = '';
errorMsg.value = '';
} catch (err) {
handleUnknownError(err);
errorMsg.value = 'Error fetching email, try again!'
confirmationMsg.value = ''
}
......@@ -40,6 +42,7 @@ const handleSubmit = async () => {
confirmationMsg.value = 'Email updated successfully!'
errorMsg.value = '';
} catch (err) {
handleUnknownError(err);
errorMsg.value = "Error updating email, try again!";
confirmationMsg.value = ''
}
......
......@@ -37,6 +37,7 @@
import { ref } from 'vue'
import BaseInput from '@/components/BaseComponents/Input/BaseInput.vue'
import { type PasswordUpdateDTO, UserService } from '@/api'
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const oldPasswordRef = ref('');
const newPasswordRef = ref('');
......@@ -71,13 +72,8 @@ const handleSubmit = async () => {
const response = UserService.updatePassword({ requestBody: updateUserPayload })
console.log(response)
} catch (err) {
handleUnknownError(err);
console.error(err)
}
}
</script>
<style scoped></style>
\ No newline at end of file
</script>
\ No newline at end of file
<template>
<div id="background">
<br>
<div id="dropdownContainer">
<br />
<div id="dropdownContainer">
<h1 class="box">Butikk</h1>
<div>
<p class="mb-1 h2" data-cy="points">{{points}}<img src="@/assets/items/pigcoin.png" style="width: 4rem"></p>
<p class="mb-1 h2" data-cy="points">{{ points }}<img src="@/assets/items/pigcoin.png" style="width: 4rem" /></p>
</div>
</div>
<div class="container d-flex justify-content-center">
</div>
<div class="container d-flex justify-content-center">
<div class="row col-md-10">
<div class="col-md-12">
<h1>Stash</h1>
<div class="category row justify-content-between mb-5 m-2">
<div class="card text-center" style="width: 16rem; border: none">
<img src="../../assets/items/adfree.png" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Adfree</h5>
<button type="button" class="btn btn-primary" id="buttonStyle" @click="buyNoAds">
+35kr</button>
</div>
</div>
<div class="card text-center" style="width: 16rem; border: none">
<img src="../../assets/items/piggybank.webp" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Premium</h5>
<button type="button" class="btn btn-primary" id="buttonStyle"
@click="buyPremium">+50kr</button>
</div>
</div>
<div class="col-md-12">
<h1>Stash</h1>
<div class="category row mb-2 m-2">
<div class="card text-center justify-content-center align-items-center" style="width: 8rem; border: none">
<img src="../../assets/items/adfree.png" class="card-img-top" alt="..." style="width: 100px; height: 100px;" />
<div class="card-body">
<h5 class="card-title">Adfree</h5>
<button type="button" class="btn btn-primary" id="buttonStyle" @click="buyNoAds">
+35kr
</button>
</div>
</div>
<div class="card text-center justify-content-center align-items-center" style="width: 8rem; border: none">
<img src="../../assets/items/piggybank.webp" class="card-img-top" alt="..." style="width: 100px; height: 100px;" />
<div class="card-body">
<h5 class="card-title">Premium</h5>
<button type="button" class="btn btn-primary" id="buttonStyle" @click="buyPremium">
+50kr
</button>
</div>
</div>
</div>
<div class="col-md-12">
<h1>Items</h1>
<div class="category row justify-content-between mb-5 m-2">
<div v-for="product in products" :key="product.id" class="card text-center"
style="width: 16rem; border: none">
<img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top"
alt="..." />
<div class="card-body">
<h5 class="card-title">{{ product.itemName }}</h5>
<ShopButton v-if="!product.alreadyBought" :button-text="product.price"
@click="buyItem(product.id)"></ShopButton>
<p v-else>Owned</p>
</div>
</div>
</div>
<div class="col-md-12">
<h1>Items</h1>
<div class="category row mb-2 m-2">
<div v-for="product in products" :key="product.id" class="card text-center d-flex justify-content-center align-items-center"
style="width: 8rem; border: none">
<img :src="`http://localhost:8080/api/images/${product.imageId}`" style="width: 100px; height: 100px;" class="card-img-top" alt="..." />
<div class="card-body">
<h5 class="card-title">{{ product.itemName }}</h5>
<h6>{{ product.price }}<img src="../../assets/items/pigcoin.png" style="width: 2rem" /></h6>
<ShopButton
v-if="!product.alreadyBought"
button-text="Buy item"
:disabled="product.price > points"
@click="buyItem(product.id)"
/>
<p v-else>Owned</p>
</div>
</div>
</div>
<div class="col-md-12">
<h1>Stash</h1>
<div class="category row justify-content-between mb-5 m-2">
<div class="card text-center" style="width: 16rem; border: none">
<img src="../../assets/items/coffee.jpg" class="card-img-top" alt="...">
</div>
<div class="col-md-12">
<h1>Cool items</h1>
<div class="category row mb-2 m-2">
<div class="card text-center d-flex justify-content-center align-items-center" style="width: 8rem; border: none">
<img src="../../assets/items/coffee.jpg" class="card-img-top" alt="..." style="width: 100px; height: 100px;">
<div class="card-body">
<h5 class="card-title">Free Coffee</h5>
<ShopButton button-text="500"></ShopButton>
<h6>500<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6>
<ShopButton
button-text="Buy item"
:disabled="500 > points"
@click="buySomething()"
/>
</div>
</div>
<div class="card text-center" style="width: 16rem; border: none">
<img src="../../assets/items/viaplay.jpg" class="card-img-top" alt="...">
<div class="card text-center d-flex justify-content-center align-items-center" style="width: 8rem; border: none">
<img src="../../assets/items/viaplay.jpg" class="card-img-top" alt="..." style="width: 100px; height: 100px;">
<div class="card-body">
<h5 class="card-title">1 Month Viaplay</h5>
<ShopButton button-text="10000"></ShopButton>
<h5 class="card-title">1 Month</h5>
<h6>10 000<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6>
<ShopButton
button-text="Buy item"
:disabled="10000 > points"
@click="buySomething()"
/>
</div>
</div>
<div class="card text-center" style="width: 16rem; border: none">
<img src="../../assets/items/pirbad.png" class="card-img-top" alt="...">
<div class="card text-center d-flex justify-content-center align-items-center" style="width: 8rem; border: none">
<img src="../../assets/items/pirbad.png" class="card-img-top" alt="..." style="width: 100px; height: 100px;">
<div class="card-body">
<h5 class="card-title">-10% rabatt</h5>
<ShopButton button-text="1000"></ShopButton>
<h6>1000<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6>
<ShopButton
button-text="Buy item"
:disabled="1000 > points"
@click="buySomething()"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import ShopButton from '@/components/Shop/ShopButton.vue';
import { ref, onMounted } from 'vue';
import { UserService } from '@/api';
import { useUserInfoStore } from '@/stores/UserStore';
import { ItemService } from '@/api';
const products = ref([] as any);
const points = ref();
const getStore = async () => {
</template>
<script setup lang="ts">
import ShopButton from '@/components/Shop/ShopButton.vue';
import { ref, onMounted } from 'vue';
import { UserService } from '@/api';
import { useUserInfoStore } from '@/stores/UserStore';
import { ItemService } from '@/api';
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
const products = ref([] as any);
const points = ref();
const getStore = async () => {
try {
const response = await ItemService.getStore();
products.value = response;
const response = await ItemService.getStore();
products.value = response;
} catch (error) {
console.log(error);
handleUnknownError(error);
console.log(error);
}
}
const getPoints = async () => {
}
const getPoints = async () => {
try {
const response = await UserService.getUser();
points.value = response.point?.currentPoints;
const response = await UserService.getUser();
points.value = response.point?.currentPoints;
} catch (error) {
console.log(error);
handleUnknownError(error);
console.log(error);
}
}
const buyItem = async (itemId: number) => {
}
const buyItem = async (itemId: number) => {
try {
const response = await ItemService.buyItem({ itemId: itemId });
console.log(response);
getStore();
getPoints();
const response = await ItemService.buyItem({ itemId: itemId });
console.log(response);
getStore();
getPoints();
} catch (error) {
console.log(error);
handleUnknownError(error);
console.log(error);
}
}
const buyPremium = async () => {
}
const buyPremium = async () => {
try {
const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'PREMIUM' });
useUserInfoStore().setUserInfo({
subscriptionLevel: 'PREMIUM',
})
const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'PREMIUM' });
useUserInfoStore().setUserInfo({
subscriptionLevel: 'PREMIUM',
})
} catch (error) {
console.log(error);
handleUnknownError(error);
console.log(error);
}
}
const buyNoAds = async () => {
}
const buyNoAds = async () => {
try {
const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'NO_ADS' });
useUserInfoStore().setUserInfo({
subscriptionLevel: 'NO_ADS',
})
const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'NO_ADS' });
useUserInfoStore().setUserInfo({
subscriptionLevel: 'NO_ADS',
})
} catch (error) {
console.log(error);
handleUnknownError(error);
console.log(error);
}
}
//Just a random code generator for the feature's sake
function generateRandomCode(length = 8) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
onMounted(() => {
const buySomething = async () => {
try {
const randomCode = generateRandomCode();
alert(`Thank you for your purchase! Your code is: ${randomCode}`);
} catch (error) {
handleUnknownError(error);
console.log(error);
}
}
onMounted(() => {
getStore();
getPoints();
})
</script>
})
</script>
<style scoped>
.card {
......@@ -152,7 +198,7 @@ onMounted(() => {
border-radius: 8px;
padding-left: 5px;
padding-right: 5px;
/* Rounded corners */
height: 225px;
}
.box {
......
<!-- ShopButton.vue -->
<template>
<button type="button" class="btn btn-primary" id="buttonStyle"><img src="../../assets/items/pigcoin.png" style="width: 2rem"> +{{ buttonText }}</button>
<button
:disabled="disabled"
:class="['btn', { 'btn-primary': !disabled, 'btn-secondary': disabled }]"
id="buttonStyle"
@click="handleClick"
>
{{ buttonText }}
</button>
</template>
<script setup lang="ts">
defineProps<{ buttonText: string }>();
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
buttonText: String,
disabled: Boolean,
});
const emit = defineEmits(['click']);
const handleClick = () => {
if (!props.disabled) {
emit('click');
}
};
</script>
<style scoped>
#buttonStyle {
border-radius: 3rem;
}
</style>
\ No newline at end of file
#buttonStyle {
border-radius: 1rem;
cursor: pointer;
}
#buttonStyle[disabled] {
cursor: not-allowed;
}
</style>
......@@ -7,15 +7,9 @@ import { useUserInfoStore } from '@/stores/UserStore';
<template>
<Menu data-cy="menu"></Menu>
<div v-if="!useUserInfoStore().isPremium && !useUserInfoStore().isNoAds" style="display: flex; flex-direction: row;">
<img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture">
</div>
<div id="minHeight">
<RouterView />
</div>
<div v-if="!useUserInfoStore().isPremium && !useUserInfoStore().isNoAds" style="display: flex; flex-direction: row;">
<img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture">
</div>
<Footer></Footer>
</template>
......
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