Skip to content

Commit

Permalink
feat: add global error handling. (#13)
Browse files Browse the repository at this point in the history
* ci: update PR labelers.

* feat: add global error handling.
  • Loading branch information
ZL-Asica authored Nov 28, 2024
1 parent 3c54023 commit 53c3229
Show file tree
Hide file tree
Showing 11 changed files with 287 additions and 23 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/code-lint-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ jobs:
build-and-deploy:
name: 🛠️ Code linter and formatter
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write

steps:
- name: 📥 Checkout Code
Expand Down
91 changes: 91 additions & 0 deletions .github/workflows/label-pr-based-on-paths.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Auto-label PR based on file paths

on:
pull_request:
types: [opened, synchronize]

jobs:
label:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Label PR based on changes with colors
uses: actions/github-script@v7
with:
script: |
const prFiles = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
// Define the labels and their colors
const labelsToColor = {
components: '1f77b4', // Blue - Components Related
pages: 'ff7f0e', // Orange - Pages Related
stores: '2ca02c', // Green - Stores Related (for Vuex or Pinia)
server: '9467bd', // Purple - Server Related
layouts: 'ffdd57', // Yellow - Layouts Related
assets: 'd62728', // Red - Assets Related
i18n: '8c564b', // Brown - i18n Related
types: 'e377c2', // Pink - Types Related
dependencies: 'e377c2', // Pink - Dependencies Related
};
const labels = new Set();
const labelPaths = {
components: 'components',
pages: ['pages', 'app.vue'],
stores: ['store', 'stores'],
server: 'server',
layouts: 'layouts',
assets: ['public', 'assets'],
i18n: 'i18n',
types: 'types',
dependencies: ['package.json', 'pnpm-lock.yaml']
};
prFiles.data.forEach(file => {
Object.keys(labelPaths).forEach(label => {
const paths = Array.isArray(labelPaths[label]) ? labelPaths[label] : [labelPaths[label]];
if (paths.some(path => file.filename.startsWith(path))) {
labels.add(label);
}
});
});
if (labels.size > 0) {
for (const label of labels) {
try {
// Check if the label exists
await github.rest.issues.getLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label
});
} catch (error) {
// If label doesn't exist, create it with the specified color
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
color: labelsToColor[label] || 'b0b0b0', // Use default gray if no color specified
});
}
}
// Add labels to the PR
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: Array.from(labels)
});
}
93 changes: 93 additions & 0 deletions .github/workflows/label-pr-size.yml.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: size-label

on:
pull_request:
types: [opened, synchronize]

jobs:
size-label:
permissions:
contents: read
pull-requests: write
issues: write
runs-on: ubuntu-latest

steps:
- name: 🛎️ Checkout repository
uses: actions/checkout@v4

- name: Determine PR size and add label
id: size-label
uses: pascalgn/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
IGNORED: |
yarn.lock
package-lock.json
pnpm-lock.yaml
package.json
.pnp.*
dist/
build/
.cache/
LICENSE
with:
sizes: >
{
"0": "XS",
"50": "S",
"150": "M",
"500": "L",
"1000": "XL",
"3000": "XXL"
}
- name: Set label colors
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const labelsToColor = {
'XS': 'd4c5f9', // Light purple
'S': 'c2e0c6', // Light green
'M': 'f9d0c4', // Light red
'L': 'f7c6c7', // Light pink
'XL': 'fef2c0', // Light yellow
'XXL': 'e99695', // Light coral
};
const sizeLabel = ${{ steps.size-label.outputs.sizeLabel }};
const color = labelsToColor[sizeLabel] || 'b0b0b0';
if (sizeLabel) {
try {
await github.rest.issues.updateLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: sizeLabel,
color: color,
});
} catch (error) {
// Label doesn't exist, create it
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: sizeLabel,
color: color,
});
}
}
- name: Comment on large PRs
if: ${{ contains('XL XXL', steps.size-label.outputs.sizeLabel) }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: "This PR is too large and may need to be broken into smaller pieces."
});
20 changes: 4 additions & 16 deletions app.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
<template>
<div
class="flex min-h-screen flex-col bg-light-background text-light-foreground dark:bg-dark-background dark:text-dark-foreground"
>
<NuxtRouteAnnouncer />
<NuxtRouteAnnouncer />

<UiProgressBar />
<UiBackToTop />

<SiteHeader />
<main class="container mx-auto max-w-7xl flex-grow px-4 py-8">
<NuxtPage />
</main>
<SiteFooter />
</div>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

<script setup>
import SiteHeader from '~/components/layout/SiteHeader.vue';
import SiteFooter from '~/components/layout/SiteFooter.vue';
const { t } = useI18n();
useSeoMeta({
Expand Down
7 changes: 3 additions & 4 deletions components/layout/SiteHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
src="/logo.webp"
alt="Site Logo"
class="h-8 w-8 md:h-10 md:w-10"
placeholder
/>

<!-- Title -->
Expand Down Expand Up @@ -44,7 +45,7 @@
isOpen ? 'translate-x-0 opacity-100' : 'translate-x-full opacity-0'
"
>
<HeaderMenu
<LayoutSiteHeaderMenu
:is-mobile="true"
ul-class-name="flex flex-col items-start gap-4 p-6"
@click-handler="toggleOpen"
Expand All @@ -60,7 +61,7 @@
/>

<!-- Desktop Menu -->
<HeaderMenu
<LayoutSiteHeaderMenu
:is-mobile="false"
ul-class-name="hidden md:flex md:gap-6"
/>
Expand All @@ -69,8 +70,6 @@
</template>

<script lang="ts" setup>
import HeaderMenu from './SiteHeaderMenu.vue';
const siteTitle = 'Trans in Academia!';
const mobileSiteTitle = 'TiA!';
Expand Down
4 changes: 3 additions & 1 deletion components/pages/EventList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
:src="event.image"
:alt="event.title"
class="mb-4 w-full rounded-lg object-cover"
placeholder
/>

<!-- Title / Available Languages -->
Expand All @@ -67,7 +68,8 @@
<NuxtLink
v-for="link in event.links"
:key="link.label"
:href="link.url"
:to="link.url"
target="_blank"
class="rounded bg-tiaBlue px-4 py-2 text-white no-underline transition-transform duration-700 hover:scale-105 hover:bg-tiaBlue-dark dark:bg-tiaPink dark:hover:bg-tiaPink-dark"
>
{{ link.label }}
Expand Down
4 changes: 2 additions & 2 deletions components/pages/SocialLinks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
<NuxtLink
v-for="(social, index) in socialLinks"
:key="index"
:href="social.href"
:to="social.href"
target="_blank"
rel="noopener noreferrer"
class="flex flex-col items-center no-underline transition-transform duration-700 hover:scale-105"
>
<NuxtImg
:src="social.icon"
alt="social.label"
class="mb-2 h-12 w-12 overflow-hidden rounded-2xl object-cover md:h-16 md:w-16"
placeholder
/>
<span class="font-sans text-xs font-semibold sm:text-sm md:text-base">
{{ social.label }}
Expand Down
43 changes: 43 additions & 0 deletions error.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<NuxtLayout name="default">
<div
class="mx-8 mt-[30vh] flex flex-col items-center justify-center text-center"
>
<h1 class="mb-4 text-2xl font-bold text-tiaPink">
{{
error.statusCode === 404
? $t('error.notFound.title')
: error.statusCode === 401
? $t('error.unauthorized.title')
: $t('error.default.title')
}}
</h1>
<p class="mb-6">
{{
error.statusCode === 404
? $t('error.notFound.description')
: error.statusCode === 401
? $t('error.unauthorized.description')
: $t('error.default.description')
}}
</p>
<button
class="rounded bg-tiaBlue px-4 py-2 text-white hover:bg-tiaBlue-dark"
@click="$router.push('/')"
>
{{ $t('error.backToHome') }}
</button>
</div>
</NuxtLayout>
</template>

<script setup lang="ts">
import type { NuxtError } from '#app';
const _props = defineProps({
error: {
type: Object as () => NuxtError,
default: () => ({ statusCode: 500 }),
},
});
</script>
15 changes: 15 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,20 @@
"language": "Switch language",
"link": "Click to visit %{link}",
"external": "Open in a new tab"
},
"error": {
"backToHome": "Back to home",
"unauthorized": {
"title": "(¬_¬) Unauthorized",
"description": "Sorry, you need to log in or authorize to access this page 🔑"
},
"notFound": {
"title": "(;′⌒`) Page not found",
"description": "Sorry, the page you are looking for is missing or never existed 🔍"
},
"default": {
"title": "(╥﹏╥) Server error",
"description": "Sorry, something went wrong on our end, we are working on it 🛠️"
}
}
}
15 changes: 15 additions & 0 deletions i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,20 @@
"language": "切换语言",
"link": "点击跳转至 %{title}",
"external": "此链接将在新标签页中打开"
},
"error": {
"backToHome": "返回首页",
"unauthorized": {
"title": "(¬_¬) 未授权",
"description": "抱歉,您需要登录或授权才能访问这个页面 🔑"
},
"notFound": {
"title": "(;′⌒`) 页面迷路啦~",
"description": "抱歉,您要找的页面已经不见了,或者它从未存在过 🔍"
},
"default": {
"title": "(╥﹏╥) 服务器出错啦~",
"description": "抱歉,内部出现了一点问题,我们正在抢修 🛠️"
}
}
}
14 changes: 14 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<div
class="flex min-h-screen flex-col bg-light-background text-light-foreground dark:bg-dark-background dark:text-dark-foreground"
>
<UiProgressBar />
<UiBackToTop />

<LayoutSiteHeader />
<main class="container mx-auto max-w-7xl flex-grow px-4 py-8">
<slot />
</main>
<LayoutSiteFooter />
</div>
</template>

0 comments on commit 53c3229

Please sign in to comment.