Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3181195
D8494.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D8494.diff
View Options
diff --git a/keyserver/src/creators/day-creator.js b/keyserver/src/creators/day-creator.js
--- a/keyserver/src/creators/day-creator.js
+++ b/keyserver/src/creators/day-creator.js
@@ -3,9 +3,11 @@
import { ServerError } from 'lib/utils/errors.js';
import createIDs from './id-creator.js';
-import { dbQuery, SQL } from '../database/database.js';
-
-const MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE = 1062;
+import {
+ dbQuery,
+ MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE,
+ SQL,
+} from '../database/database.js';
async function fetchOrCreateDayID(
threadID: string,
diff --git a/keyserver/src/creators/invite-link-creator.js b/keyserver/src/creators/invite-link-creator.js
--- a/keyserver/src/creators/invite-link-creator.js
+++ b/keyserver/src/creators/invite-link-creator.js
@@ -8,7 +8,11 @@
import { ServerError } from 'lib/utils/errors.js';
import createIDs from './id-creator.js';
-import { dbQuery, SQL } from '../database/database.js';
+import {
+ dbQuery,
+ MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE,
+ SQL,
+} from '../database/database.js';
import { fetchPrimaryInviteLinks } from '../fetchers/link-fetchers.js';
import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js';
@@ -21,7 +25,7 @@
request: CreateOrUpdatePublicLinkRequest,
): Promise<InviteLink> {
if (!secretRegex.test(request.name)) {
- throw new ServerError('invalid_parameters');
+ throw new ServerError('invalid_characters');
}
const permissionPromise = checkThreadPermission(
@@ -64,7 +68,10 @@
`;
try {
await dbQuery(query);
- } catch {
+ } catch (e) {
+ if (e.errno === MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE) {
+ throw new ServerError('already_in_use');
+ }
throw new ServerError('invalid_parameters');
}
return {
@@ -92,17 +99,21 @@
)
`;
let result = null;
+ const deleteIDs = SQL`
+ DELETE FROM ids
+ WHERE id = ${id}
+ `;
try {
result = (await dbQuery(createLinkQuery))[0];
- } catch {
+ } catch (e) {
+ await dbQuery(deleteIDs);
+ if (e.errno === MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE) {
+ throw new ServerError('already_in_use');
+ }
throw new ServerError('invalid_parameters');
}
if (result.affectedRows === 0) {
- const deleteIDs = SQL`
- DELETE FROM ids
- WHERE id = ${id}
- `;
await dbQuery(deleteIDs);
throw new ServerError('invalid_parameters');
}
diff --git a/keyserver/src/database/database.js b/keyserver/src/database/database.js
--- a/keyserver/src/database/database.js
+++ b/keyserver/src/database/database.js
@@ -13,6 +13,8 @@
const SQLStatement: SQLStatementType = SQL.SQLStatement;
+const MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE = 1062;
+
let migrationConnection;
async function getMigrationConnection() {
if (migrationConnection) {
@@ -203,4 +205,5 @@
setConnectionContext,
dbQuery,
rawSQL,
+ MYSQL_DUPLICATE_ENTRY_FOR_KEY_ERROR_CODE,
};
diff --git a/lib/shared/invite-links.js b/lib/shared/invite-links.js
new file mode 100644
--- /dev/null
+++ b/lib/shared/invite-links.js
@@ -0,0 +1,11 @@
+// @flow
+
+const inviteLinkErrorMessages = {
+ invalid_characters: 'Link cannot contain any spaces or special characters.',
+ offensive_words: 'No offensive or abusive words allowed.',
+ already_in_use: 'Public link URL already in use.',
+};
+
+const defaultErrorMessage = 'Unknown error.';
+
+export { inviteLinkErrorMessages, defaultErrorMessage };
diff --git a/native/invite-links/manage-public-link-screen.react.js b/native/invite-links/manage-public-link-screen.react.js
--- a/native/invite-links/manage-public-link-screen.react.js
+++ b/native/invite-links/manage-public-link-screen.react.js
@@ -6,6 +6,10 @@
import { inviteLinkUrl } from 'lib/facts/links.js';
import { useInviteLinksActions } from 'lib/hooks/invite-links.js';
import { primaryInviteLinksSelector } from 'lib/selectors/invite-links-selectors.js';
+import {
+ defaultErrorMessage,
+ inviteLinkErrorMessages,
+} from 'lib/shared/invite-links.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import Button from '../components/button.react.js';
@@ -40,7 +44,11 @@
let errorComponent = null;
if (error) {
- errorComponent = <Text style={styles.error}>{error}</Text>;
+ errorComponent = (
+ <Text style={styles.error}>
+ {inviteLinkErrorMessages[error] ?? defaultErrorMessage}
+ </Text>
+ );
}
const onDisableButtonClick = React.useCallback(() => {
diff --git a/web/invite-links/manage/edit-link-modal.react.js b/web/invite-links/manage/edit-link-modal.react.js
--- a/web/invite-links/manage/edit-link-modal.react.js
+++ b/web/invite-links/manage/edit-link-modal.react.js
@@ -6,6 +6,10 @@
import { useModalContext } from 'lib/components/modal-provider.react.js';
import { inviteLinkUrl } from 'lib/facts/links.js';
import { useInviteLinksActions } from 'lib/hooks/invite-links.js';
+import {
+ defaultErrorMessage,
+ inviteLinkErrorMessages,
+} from 'lib/shared/invite-links.js';
import type { InviteLink } from 'lib/types/link-types.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
@@ -40,7 +44,11 @@
let errorComponent = null;
if (error) {
- errorComponent = <div className={css.errorContainer}>{error}</div>;
+ errorComponent = (
+ <div className={css.errorContainer}>
+ {inviteLinkErrorMessages[error] ?? defaultErrorMessage}
+ </div>
+ );
}
let disableLinkComponent = null;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 9, 5:42 AM (20 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2449411
Default Alt Text
D8494.diff (5 KB)
Attached To
Mode
D8494: [keyserver][web][native] Handle link creation / update errors
Attached
Detach File
Event Timeline
Log In to Comment