diff --git a/src/def/messages.ts b/src/def/messages.ts
index 2d5410ba..2f051c37 100644
--- a/src/def/messages.ts
+++ b/src/def/messages.ts
@@ -1,9 +1,11 @@
export enum GucchoError {
- UnknownError = 1,
+ UnknownError = -1,
+ AssertionError,
MissingServerAvatarConfig,
// basic
ModeNotSupported = 1000,
+ ModeOrRulesetNotSupported,
InvalidId,
// user
@@ -20,7 +22,6 @@ export enum GucchoError {
// auth
IncorrectPassword = 3000,
-
PasswordNotMatch,
OldPasswordMismatch,
EmailTokenNotFound,
@@ -48,4 +49,10 @@ export enum GucchoError {
ScoreNotFound = 8000,
// clan
ClanNotFound = 9000,
+
+ // article
+ ArticleNotFound = 10000,
+ InsufficientPrivilegeToEditArticle,
+ FileSystemArticlePathOutsideArticleRoot,
+ TryingToDeleteFallbackContents,
}
diff --git a/src/locales/base/de-DE.ts b/src/locales/base/de-DE.ts
index fd3f57b8..a86f61e8 100644
--- a/src/locales/base/de-DE.ts
+++ b/src/locales/base/de-DE.ts
@@ -147,6 +147,13 @@ export default {
[GucchoError.ScoreNotFound]: 'Score nicht gefunden.',
[GucchoError.UnableToUpdateSession]: 'Fehler beim aktualisieren der Session.',
[GucchoError.ClanNotFound]: 'Clan nicht gefunden.',
+ // TODO DE translation (hint: use TS autocomplete)
+ // [GucchoError.AssertionError]: '',
+ // [GucchoError.ModeOrRulesetNotSupported]: '',
+ // [GucchoError.InsufficientPrivilegeToEditArticle]: '',
+ // [GucchoError.FileSystemArticlePathOutsideArticleRoot]: '',
+ // [GucchoError.TryingToDeleteFallbackContents]: ''
+ // [GucchoError.ArticleNotFound]: '',
},
country: {
[CountryCode.Unknown]: 'Unbekannt',
@@ -405,15 +412,15 @@ export default {
subject: '{serverName} - Konto Verifikation',
content: `
Hallo,
-
+
um deine Email für {serverName} zu verifizieren, bitte folge dem Link:
{link}
-
+
Alternativ, kannst du auch den folgenden Code benutzen: {otp}
-
+
Die Verifikation ist gültig für {ttl} Minuten.
Lass uns wissen, wenn du irgendwelche Fragen hast.
-
+
{serverName}
`,
},
@@ -421,14 +428,14 @@ export default {
subject: '{serverName} - Konto Wiederherstellung',
content: `
Hallo {name},
-
+
um dein Passwort für {serverName} zurückzusetzen, bitte folge dem folgenden Link:
{link}
-
+
Alternativ kannst du auch den folgenden Code benutzen: {otp}
-
+
Die Verifikation ist gültig für {ttl} Minuten.
-
+
{serverName}
`,
},
@@ -436,12 +443,12 @@ export default {
subject: '{serverName} - E-Mail-Adresse ändern',
content: `
Hallo {name},
-
+
um deine E-Mail-Adresse für {serverName} zu ändern, benutze bitte den folgenden Code:
{otp}
-
+
Die Verifikation ist gültig für {ttl} Minuten.
-
+
{serverName}
`,
},
diff --git a/src/locales/base/en-GB.ts b/src/locales/base/en-GB.ts
index 8ef67d81..6054172e 100644
--- a/src/locales/base/en-GB.ts
+++ b/src/locales/base/en-GB.ts
@@ -74,7 +74,6 @@ export default {
role: {
[UserRole.Disabled]: 'Disabled',
[UserRole.Restricted]: 'Restricted',
- // [UserRole.Registered]: 'Registered',
[UserRole.Inactive]: 'Inactive',
[UserRole.Supported]: 'Supported',
[UserRole.Supporter]: 'Supporter',
@@ -133,6 +132,7 @@ export default {
[GucchoError.ConflictRelation]: 'You already have a relation with this player.',
[GucchoError.MissingServerAvatarConfig]: 'The server is not configured correctly; avatar location is missing.',
[GucchoError.ModeNotSupported]: 'Mode not supported.',
+ [GucchoError.ModeOrRulesetNotSupported]: 'Mode or ruleset not supported.',
[GucchoError.UpdateUserpageFailed]: 'Failed to update user page.',
[GucchoError.MimeNotImage]: 'The provided file is not an image.',
[GucchoError.HackerTryingToDeleteAllAvatars]: 'SOMEONE IS ATTEMPTING TO DELETE ALL AVATARS.',
@@ -147,6 +147,11 @@ export default {
[GucchoError.ScoreNotFound]: 'Score not found.',
[GucchoError.UnableToUpdateSession]: 'Unable to update session.',
[GucchoError.ClanNotFound]: 'Clan not found.',
+ [GucchoError.AssertionError]: 'Assertion Error: Something unexpected happened!',
+ [GucchoError.InsufficientPrivilegeToEditArticle]: 'You can not edit this article due to insufficient privilege.',
+ [GucchoError.FileSystemArticlePathOutsideArticleRoot]: 'Prohibited Saving article outside articles path.',
+ [GucchoError.TryingToDeleteFallbackContents]: 'Trying to delete fallback contents.',
+ [GucchoError.ArticleNotFound]: 'Article not found.',
},
country: {
[CountryCode.Unknown]: 'Unknown',
diff --git a/src/locales/base/zh-CN.ts b/src/locales/base/zh-CN.ts
index c5f8d100..bf1c7b9b 100644
--- a/src/locales/base/zh-CN.ts
+++ b/src/locales/base/zh-CN.ts
@@ -112,6 +112,7 @@ export default {
[GucchoError.UnknownError]: '未知错误。',
[GucchoError.MissingServerAvatarConfig]: '头像配置缺失。',
[GucchoError.ModeNotSupported]: '不支持的模式。',
+ [GucchoError.ModeOrRulesetNotSupported]: '不支持的模式或玩法。',
[GucchoError.UserNotFound]: '找不到用户。',
[GucchoError.UserExists]: '已有此用户。',
[GucchoError.ConflictEmail]: '邮箱已被使用。',
@@ -140,6 +141,11 @@ export default {
[GucchoError.ScoreNotFound]: '找不到成绩。',
[GucchoError.UnableToUpdateSession]: '无法更新会话。',
[GucchoError.ClanNotFound]: '找不到家人。',
+ [GucchoError.AssertionError]: '断言发生错误。不应该出现此状态!',
+ [GucchoError.InsufficientPrivilegeToEditArticle]: '您没有权限修改此文章。',
+ [GucchoError.FileSystemArticlePathOutsideArticleRoot]: '保存路径在文章目录以外。',
+ [GucchoError.TryingToDeleteFallbackContents]: '正在尝试删除缺省的内容。',
+ [GucchoError.ArticleNotFound]: '找不到文章。',
},
country: {
diff --git a/src/pages/article/[...id].vue b/src/pages/article/[...id].vue
index f060f216..fc4c85e5 100644
--- a/src/pages/article/[...id].vue
+++ b/src/pages/article/[...id].vue
@@ -1,28 +1,38 @@
en-GB:
edit: Edit
+ error:
+ no-id: No article Id provided.
zh-CN:
edit: 编辑
+ error:
+ no-id: 没有提供文章ID。
fr-FR:
edit: Modifier
+ # TODO fr translation
+ error:
+ no-id: No article Id provided.
de-DE:
edit: Bearbeiten
+ # TODO update de translation
+ error:
+ no-id: No article Id provided.
diff --git a/src/server/backend/$base/server/article/index.ts b/src/server/backend/$base/server/article/index.ts
index 6a66e852..837505b2 100644
--- a/src/server/backend/$base/server/article/index.ts
+++ b/src/server/backend/$base/server/article/index.ts
@@ -12,6 +12,7 @@ import { latest, paths, v0, versions } from './v'
import useEditorExtensions from '~/composables/useEditorExtensionsServer'
import type { UserCompact, UserRole } from '~/def/user'
import { Logger } from '$base/logger'
+import { GucchoError } from '~/def/messages'
const logger = Logger.child({ label: 'article' })
@@ -116,7 +117,7 @@ export abstract class ArticleProvider {
dynamic: boolean
}): Promise {
if (!opt.user.roles.find(role => ['admin', 'owner'].includes(role))) {
- throw new Error('you have insufficient privilege to edit this article')
+ throwGucchoError(GucchoError.InsufficientPrivilegeToEditArticle)
}
const pContent = ArticleProvider.createContent(opt)
let meta: ArticleProvider.Meta
@@ -150,14 +151,14 @@ export abstract class ArticleProvider {
static async deleteLocal(opt: { slug: string; user: UserCompact }) {
const { user, slug } = opt
if (!user.roles.find(role => ['admin', 'owner'].includes(role))) {
- throw new Error('you have insufficient privilege to edit this article')
+ throwGucchoError(GucchoError.InsufficientPrivilegeToEditArticle)
}
const loc = join(ArticleProvider.articles, slug)
if (!ArticleProvider.inside(loc)) {
- throw new Error('dangerous operation')
+ throwGucchoError(GucchoError.FileSystemArticlePathOutsideArticleRoot)
}
if (!relative(join(ArticleProvider.articles, './fallbacks'), loc).startsWith('..')) {
- throw new Error('trying to delete fallback contents')
+ throwGucchoError(GucchoError.TryingToDeleteFallbackContents)
}
return await fs.rm(loc)
}
diff --git a/src/server/backend/bancho.py/server/rank.ts b/src/server/backend/bancho.py/server/rank.ts
index dfd18732..76383006 100644
--- a/src/server/backend/bancho.py/server/rank.ts
+++ b/src/server/backend/bancho.py/server/rank.ts
@@ -316,11 +316,6 @@ export class RedisRankProvider extends DatabaseRankProvider implements Monitored
const start = page * pageSize
const bPyMode = toBanchoPyMode(mode, ruleset)
- if (bPyMode === undefined) {
- // throw new Error('no mode')
- raise(Error, 'no mode')
- }
-
// user.id[]
const rank = await this.getPPv2LiveLeaderboard(bPyMode, 0, start + pageSize * 2).then(res => res.map(Number))
diff --git a/src/server/backend/bancho.py/transforms/mode.ts b/src/server/backend/bancho.py/transforms/mode.ts
index 7531df63..e083373a 100644
--- a/src/server/backend/bancho.py/transforms/mode.ts
+++ b/src/server/backend/bancho.py/transforms/mode.ts
@@ -2,6 +2,7 @@ import { match } from 'switch-pattern'
import { BanchoMode, BanchoPyMode } from '../enums'
import { Mode, Ruleset } from '~/def'
import type { ActiveMode, ActiveRuleset } from '~/def/common'
+import { GucchoError } from '~/def/messages'
export const BPyMode = {
[BanchoPyMode.OsuStandard]: [Mode.Osu, Ruleset.Standard],
@@ -25,7 +26,7 @@ export function toBanchoPyMode(
const str = BPyModeEntries.find(([_, mr]) => patterns.exact(mr))?.[0]
if (!str) {
- throw new Error('not supported')
+ throwGucchoError(GucchoError.ModeOrRulesetNotSupported)
}
return Number.parseInt(str)
}
diff --git a/src/server/routes/mail/verify.ts b/src/server/routes/mail/verify.ts
index cc29fa55..004449cd 100644
--- a/src/server/routes/mail/verify.ts
+++ b/src/server/routes/mail/verify.ts
@@ -19,7 +19,7 @@ const jumpMap: Record