Log server side auth error + slackbot pagination fix (#4149)

This commit is contained in:
pablonyx 2025-02-27 18:05:28 -08:00 committed by GitHub
parent 0a24dbc52c
commit eb369384a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 106 additions and 40 deletions

View File

@ -343,7 +343,8 @@ def list_bot_configs(
]
MAX_CHANNELS = 200
MAX_SLACK_PAGES = 5
SLACK_API_CHANNELS_PER_PAGE = 100
@router.get(
@ -355,8 +356,8 @@ def get_all_channels_from_slack_api(
_: User | None = Depends(current_admin_user),
) -> list[SlackChannel]:
"""
Fetches all channels from the Slack API.
If the workspace has 200 or more channels, we raise an error.
Fetches channels the bot is a member of from the Slack API.
Handles pagination with a limit to avoid excessive API calls.
"""
tokens = fetch_slack_bot_tokens(db_session, bot_id)
if not tokens or "bot_token" not in tokens:
@ -365,28 +366,60 @@ def get_all_channels_from_slack_api(
)
client = WebClient(token=tokens["bot_token"])
all_channels = []
next_cursor = None
current_page = 0
try:
response = client.conversations_list(
types="public_channel,private_channel",
exclude_archived=True,
limit=MAX_CHANNELS,
)
# Use users_conversations with limited pagination
while current_page < MAX_SLACK_PAGES:
current_page += 1
# Make API call with cursor if we have one
if next_cursor:
response = client.users_conversations(
types="public_channel,private_channel",
exclude_archived=True,
cursor=next_cursor,
limit=SLACK_API_CHANNELS_PER_PAGE,
)
else:
response = client.users_conversations(
types="public_channel,private_channel",
exclude_archived=True,
limit=SLACK_API_CHANNELS_PER_PAGE,
)
# Add channels to our list
if "channels" in response and response["channels"]:
all_channels.extend(response["channels"])
# Check if we need to paginate
if (
"response_metadata" in response
and "next_cursor" in response["response_metadata"]
):
next_cursor = response["response_metadata"]["next_cursor"]
if next_cursor:
if current_page == MAX_SLACK_PAGES:
raise HTTPException(
status_code=400,
detail="Workspace has too many channels to paginate over in this call.",
)
continue
# If we get here, no more pages
break
channels = [
SlackChannel(id=channel["id"], name=channel["name"])
for channel in response["channels"]
for channel in all_channels
]
if len(channels) == MAX_CHANNELS:
raise HTTPException(
status_code=400,
detail=f"Workspace has {MAX_CHANNELS} or more channels.",
)
return channels
except SlackApiError as e:
# Handle rate limiting or other API errors
raise HTTPException(
status_code=500,
detail=f"Error fetching channels from Slack API: {str(e)}",

View File

@ -199,17 +199,17 @@ export function SlackChannelConfigFormFields({
<Badge variant="agent" className="bg-blue-100 text-blue-800">
Default Configuration
</Badge>
<p className="mt-2 text-sm text-gray-600">
<p className="mt-2 text-sm text-neutral-600">
This default configuration will apply across all Slack channels
the bot is added to in the Slack workspace, as well as direct
messages (DMs), unless disabled.
</p>
<div className="mt-4 p-4 bg-gray-100 rounded-md border border-gray-300">
<div className="mt-4 p-4 bg-neutral-100 rounded-md border border-neutral-300">
<CheckFormField
name="disabled"
label="Disable Default Configuration"
/>
<p className="mt-2 text-sm text-gray-600 italic">
<p className="mt-2 text-sm text-neutral-600 italic">
Warning: Disabling the default configuration means the bot
won&apos;t respond in Slack channels or DMs unless explicitly
configured for them.
@ -238,20 +238,28 @@ export function SlackChannelConfigFormFields({
/>
</div>
) : (
<Field name="channel_name">
{({ field, form }: { field: any; form: any }) => (
<SearchMultiSelectDropdown
options={channelOptions || []}
onSelect={(selected) => {
form.setFieldValue("channel_name", selected.name);
}}
initialSearchTerm={field.value}
onSearchTermChange={(term) => {
form.setFieldValue("channel_name", term);
}}
/>
)}
</Field>
<>
<Field name="channel_name">
{({ field, form }: { field: any; form: any }) => (
<SearchMultiSelectDropdown
options={channelOptions || []}
onSelect={(selected) => {
form.setFieldValue("channel_name", selected.name);
}}
initialSearchTerm={field.value}
onSearchTermChange={(term) => {
form.setFieldValue("channel_name", term);
}}
/>
)}
</Field>
<p className="mt-2 text-sm dark:text-neutral-400 text-neutral-600">
Note: This list shows public and private channels where the
bot is a member (up to 500 channels). If you don&apos;t see a
channel, make sure the bot is added to that channel in Slack
first, or type the channel name manually.
</p>
</>
)}
</>
)}

View File

@ -0,0 +1,16 @@
export default function AuthErrorLayout({
children,
}: {
children: React.ReactNode;
}) {
// Log error to console for debugging
console.error(
"Authentication error page was accessed - this should not happen in normal flow"
);
// In a production environment, you might want to send this to your error tracking service
// For example, if using a service like Sentry:
// captureException(new Error("Authentication error page was accessed unexpectedly"));
return <>{children}</>;
}

View File

@ -4,6 +4,7 @@ import AuthFlowContainer from "@/components/auth/AuthFlowContainer";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import { FiLogIn } from "react-icons/fi";
import { NEXT_PUBLIC_CLOUD_ENABLED } from "@/lib/constants";
const Page = () => {
return (
@ -15,19 +16,21 @@ const Page = () => {
<p className="text-text-700 text-center">
We encountered an issue while attempting to log you in.
</p>
<div className="bg-red-50 border border-red-200 rounded-lg p-4 shadow-sm">
<h3 className="text-red-800 font-semibold mb-2">Possible Issues:</h3>
<div className="bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 rounded-lg p-4 shadow-sm">
<h3 className="text-red-800 dark:text-red-400 font-semibold mb-2">
Possible Issues:
</h3>
<ul className="space-y-2">
<li className="flex items-center text-red-700">
<div className="w-2 h-2 bg-red-500 rounded-full mr-2"></div>
<li className="flex items-center text-red-700 dark:text-red-400">
<div className="w-2 h-2 bg-red-500 dark:bg-red-400 rounded-full mr-2"></div>
Incorrect or expired login credentials
</li>
<li className="flex items-center text-red-700">
<div className="w-2 h-2 bg-red-500 rounded-full mr-2"></div>
<li className="flex items-center text-red-700 dark:text-red-400">
<div className="w-2 h-2 bg-red-500 dark:bg-red-400 rounded-full mr-2"></div>
Temporary authentication system disruption
</li>
<li className="flex items-center text-red-700">
<div className="w-2 h-2 bg-red-500 rounded-full mr-2"></div>
<li className="flex items-center text-red-700 dark:text-red-400">
<div className="w-2 h-2 bg-red-500 dark:bg-red-400 rounded-full mr-2"></div>
Account access restrictions or permissions
</li>
</ul>
@ -41,6 +44,12 @@ const Page = () => {
<p className="text-sm text-text-500 text-center">
We recommend trying again. If you continue to experience problems,
please reach out to your system administrator for assistance.
{NEXT_PUBLIC_CLOUD_ENABLED && (
<span className="block mt-1 text-blue-600">
A member of our team has been automatically notified about this
issue.
</span>
)}
</p>
</div>
</AuthFlowContainer>