20 examples

Unreachable code

Code segment that can never execute, wasting resources.

[ FAQ1 ]

What is unreachable code?

Unreachable code occurs when a portion of code is placed after statements that prevent its execution, such as a return, break, or infinite loop. Because the logic prevents these statements from ever running, compilers and analysis tools typically flag them with warnings or errors. For example, code written immediately after a return statement in a function is never executed, making it unreachable. Unreachable code negatively impacts readability, can obscure important logic, and complicates debugging and testing, affecting accurate code coverage metrics.
[ FAQ2 ]

How to fix unreachable code

To fix unreachable code, first identify these segments using compiler warnings, static analysis tools, or code coverage reports. Evaluate the logic of your functions and control flow statements (return, loops, conditionals) to confirm intended execution paths. Remove or reposition code so that all code segments have a valid and reachable execution path. If the unreachable code was mistakenly included, delete it outright to simplify the codebase. Regular code reviews and automated linting tools help proactively detect and address unreachable code, ensuring cleaner, more maintainable, and efficient software.
diff block
total_size += item_size
if total_size >= MAX_BATCH_SIZE_BYTES:
self._log.debug("hit batch size limit (size: %d)", total_size)
+ raise RuntimeError(f"hit batch size limit (size: {total_size})")
break
Greptile
greptile
logic: Unreachable code: 'break' statement after 'raise' will never execute
suggested fix
raise RuntimeError(f"hit batch size limit (size: {total_size})")
diff block
+import { homedir } from "os";
+import { executeSQL } from "@raycast/utils";
+import { DataBasePath } from "./Defines";
+
+export type Workspace = {
+ isChangedBacking: string;
+ tintColor: string;
+ flaggedSortDirection: string;
+ showQueryPreview: string;
+ archiveSortDirection: string;
+ inboxIncludesFlagged: string;
+ preferredLightTheme: string;
+ inboxSortFlaggedToTop: string;
+ loadQueryFolder: string;
+ loadActionGroupUUIDString: string;
+ tagFilter: string;
+ loadKeyboardGroupUUIDString: string;
+ inboxSortMode: string;
+ showPreview: string;
+ archiveIncludesFlagged: string;
+ tagFilterMode: string;
+ showTags: string;
+ allSortFlaggedToTop: string;
+ showDate: string;
+ allSortMode: string;
+ queryString: string;
+ name: string;
+ dateRangeSpecifier: {
+ endSpecifier: {
+ specifierType: string;
+ isEnabled: boolean;
+ absolute: number;
+ relativeDays: number;
+ field: string;
+ };
+ startSpecifier: {
+ isEnabled: boolean;
+ specifierType: string;
+ field: string;
+ absolute: number;
+ relativeDays: number;
+ };
+ };
+ showLastAction: string;
+ previewSize: string;
+ archiveSortFlaggedToTop: string;
+ allSortDirection: string;
+ lastClonedKey: string;
+ icon: string;
+ inboxSortDirection: string;
+ flaggedStatus: string;
+ visibility: string;
+ archiveSortMode: string;
+ flaggedSortMode: string;
+ key: string;
+ preferredDarkTheme: string;
+};
+
+const DRAFTS_DB = DataBasePath.replace("~", homedir());
+
+export async function getWorkspaces() {
+ const dQuery = `
+ SELECT
+ ZVALUE as value
+ FROM
+ ZMANAGEDSTORAGE
+ WHERE
+ ZTYPE == "workspace"
+ ORDER BY
+ ZSORT_INDEX ASC
+ `;
+
+ // Assuming executeSQL is a function that executes the SQL and returns results
+ const rawData = await executeSQL<{ value: string }>(DRAFTS_DB, dQuery);
+
+ if (!rawData || rawData.length === 0) {
+ return [];
+ }
+
+ // Parse the JSON and map to Workspace objects
+ const workspaces = rawData
+ .map((row) => {
+ try {
+ return JSON.parse(row.value) as Workspace;
+ } catch (error) {
+ console.error("Failed to parse workspace JSON:", error);
+ return null;
+ }
+ })
+ .filter((workspace): workspace is Workspace => workspace !== null)
+ .filter((workspace) => workspace.name.length > 0);
+
+ // Use a Set to filter out duplicate workspace names
+ const uniqueWorkspacesMap = new Map<string, Workspace>();
+ for (const workspace of workspaces) {
+ if (!uniqueWorkspacesMap.has(workspace.name)) {
+ uniqueWorkspacesMap.set(workspace.name, workspace);
+ }
+ }
+
+ return Array.from(uniqueWorkspacesMap.values());
+ return workspaces;
Greptile
greptile
logic: Unreachable code: remove the second return statement (line 102) as it's never executed.
suggested fix
return Array.from(uniqueWorkspacesMap.values());
diff block
-import { Accordion } from "@/components/Accordion";
-import { Heading } from "@/components/Heading";
-import {
- Icon,
- faExclamationTriangle,
- faInfoCircle,
- faLightbulbOn,
-} from "@rivet-gg/icons";
-import NextImage from "next/image";
-import Link from "next/link";
-
-export { ButtonGroup, Button } from "@/components/Button";
-export { ResourceGroup, Resource } from "@/components/Resources";
-export { Snippet } from "@/components/Snippet";
-export { Summary } from "@/components/Summary";
-export { Accordion, AccordionGroup } from "@/components/Accordion";
-export * from "@/components/callouts";
-export { ArticleHeader } from "@/components/ArticleHeader";
-export { ArticleSocials } from "@/components/ArticleSocials";
-import { CodeBlock } from "@/components/CodeBlock";
-import {
- Alert,
- AlertDescription,
- AlertTitle,
- Badge,
- CtaCard,
- WithTooltip,
-} from "@rivet-gg/components";
-
-import { SchemaPreview as Schema } from "@/components/SchemaPreview";
-
-export * from "@rivet-gg/components/mdx";
+import { Accordion } from '@/components/Accordion';
+import { Heading } from '@/components/Heading';
+import NextImage from 'next/image';
+import Link from 'next/link';
+
+export { ButtonGroup, Button } from '@/components/Button';
+export { ResourceGroup, Resource } from '@/components/Resources';
+export { Snippet } from '@/components/Snippet';
+export { Summary } from '@/components/Summary';
+export { Accordion, AccordionGroup } from '@/components/Accordion';
+export { ArticleHeader } from '@/components/ArticleHeader';
+export { ArticleSocials } from '@/components/ArticleSocials';
+import { CodeBlock } from '@/components/CodeBlock';
+import { Badge, CtaCard, WithTooltip } from '@rivet-gg/components';
+
+import { SchemaPreview as Schema } from '@/components/SchemaPreview';
+
+export * from '@rivet-gg/components/mdx';
export const a = Link;
-export const Image = (props) => <NextImage {...props} />;
+export const Image = props => <NextImage {...props} />;
export const h2 = function H2(props) {
- return <Heading level={2} {...props} />;
+ return <Heading level={2} {...props} />;
};
export const h3 = function H3(props) {
- return <Heading level={3} {...props} />;
+ return <Heading level={3} {...props} />;
};
export const table = function Table(props) {
- return (
- <div className="overflow-x-auto">
- <table {...props} />
- </div>
- );
+ return (
+ <div className='overflow-x-auto'>
+ <table {...props} />
+ </div>
+ );
};
export function Tooltip({ tip, children }) {
- return (
- <WithTooltip
- content={tip}
- trigger={
- <span className="underline decoration-cream-400 decoration-dotted decoration-2 underline-offset-4 dark:decoration-charcole-500">
- {children}
- </span>
- }
- />
- );
+ return (
+ <WithTooltip
+ content={tip}
+ trigger={
+ <span className='underline decoration-cream-400 decoration-dotted decoration-2 underline-offset-4 dark:decoration-charcole-500'>
+ {children}
+ </span>
+ }
+ />
+ );
}
export function ComingSoon() {
- return <Note>Documentation coming very soon!</Note>;
+ return <Note>Documentation coming very soon!</Note>;
}
export function Outdated() {
- return (
- <Info>
- 🚧 This documentation page is no longer maintained and potentially
- outdated 🚧
- </Info>
- );
+ return <Info>🚧 This documentation page is no longer maintained and potentially outdated 🚧</Info>;
}
export function WorkInProgress() {
- return <Info>🚧 This documentation page is a work in progress 🚧</Info>;
+ return <Info>🚧 This documentation page is a work in progress 🚧</Info>;
}
export function EnvTokenClient() {
- return (
- <Info>
- <p>
- In development,&nbsp;<code>RIVET_TOKEN</code> will use the
- development token generated by <code>rivet run</code>. In
- production,&nbsp;<code>RIVET_TOKEN</code> will be automatically
- added by the CDN.
- </p>
-
- <p>More info:</p>
-
- <ul>
- <li>
- <Link href="/docs/general/concepts/handling-game-tokens">
- Handling game tokens
- </Link>
- </li>
- <li>
- <Link href="/docs/general/concepts/dev-tokens">
- Development tokens
- </Link>
- </li>
- <li>
- <Link href="/docs/general/concepts/token-types#namespace-public">
- Public tokens
- </Link>
- </li>
- </ul>
- </Info>
- );
+ return (
+ <Info>
+ <p>
+ In development,&nbsp;<code>RIVET_TOKEN</code> will use the development token generated by{' '}
+ <code>rivet run</code>. In production,&nbsp;<code>RIVET_TOKEN</code> will be automatically added by
+ the CDN.
+ </p>
+
+ <p>More info:</p>
+
+ <ul>
+ <li>
+ <Link href='/docs/general/concepts/handling-game-tokens'>Handling game tokens</Link>
+ </li>
+ <li>
+ <Link href='/docs/general/concepts/dev-tokens'>Development tokens</Link>
+ </li>
+ <li>
+ <Link href='/docs/general/concepts/token-types#namespace-public'>Public tokens</Link>
+ </li>
+ </ul>
+ </Info>
+ );
}
export function EnvTokenServer() {
- return (
- <Info>
- <p>
- In development, <code>RIVET_TOKEN</code> will use the
- development token generated by <code>rivet run</code>. In
- production,&nbsp;<code>RIVET_TOKEN</code> is automatically added
- to your environment by Rivet.
- </p>
-
- <p>More info:</p>
-
- <ul>
- <li>
- <Link href="/docs/general/concepts/handling-game-tokens">
- Handling game tokens
- </Link>
- </li>
- <li>
- <Link href="/docs/general/concepts/dev-tokens">
- Development tokens
- </Link>
- </li>
- </ul>
- </Info>
- );
+ return (
+ <Info>
+ <p>
+ In development, <code>RIVET_TOKEN</code> will use the development token generated by{' '}
+ <code>rivet run</code>. In production,&nbsp;<code>RIVET_TOKEN</code> is automatically added to your
+ environment by Rivet.
+ </p>
+
+ <p>More info:</p>
+
+ <ul>
+ <li>
+ <Link href='/docs/general/concepts/handling-game-tokens'>Handling game tokens</Link>
+ </li>
+ <li>
+ <Link href='/docs/general/concepts/dev-tokens'>Development tokens</Link>
+ </li>
+ </ul>
+ </Info>
+ );
}
export function PreRivetBranch() {
- return (
- <Info>
- <p>
- The <code>pre-rivet</code> branch contains the source code of
- this project without Rivet implemented, in contrast to the{" "}
- <code>main</code> branch. View these side by side to get a good
- picture of what it takes to integrate Rivet for your game.
- </p>
- </Info>
- );
+ return (
+ <Info>
+ <p>
+ The <code>pre-rivet</code> branch contains the source code of this project without Rivet implemented,
+ in contrast to the <code>main</code> branch. View these side by side to get a good picture of what it
+ takes to integrate Rivet for your game.
+ </p>
+ </Info>
+ );
}
export function ProtocolSupportMatrix() {
- return (
- <table>
- <tr>
- <th>Protocol</th>
- <th>
- <Link href="/docs/general/dynamic-servers/game-guard">
- Rivet Game Guard
- </Link>
- </th>
- <th>
- <Link href="/docs/general/dynamic-servers/host-bridge-networking">
- Host Network (Open Source & Enterprise)
- </Link>
- </th>
- </tr>
- <tr>
- <td></td>
- <td>
- <em>Requires single port</em>
- </td>
- <td>
- <em>Requires port range</em>
- </td>
- </tr>
- <tr>
- <td>HTTPS / Secure WebSocket</td>
- <td>✅</td>
- <td></td>
- </tr>
- <tr>
- <td>HTTP / WebSocket</td>
- <td>✅</td>
- <td></td>
- </tr>
- <tr>
- <td>TCP + TLS</td>
- <td>✅</td>
- <td></td>
- </tr>
- <tr>
- <td>TCP</td>
- <td>✅</td>
- <td>✅</td>
- </tr>
- <tr>
- <td>UDP / WebRTC / ENet / KCP</td>
- <td>✅</td>
- <td>✅</td>
- </tr>
- </table>
- );
+ return (
+ <table>
+ <tr>
+ <th>Protocol</th>
+ <th>
+ <Link href='/docs/general/dynamic-servers/game-guard'>Rivet Game Guard</Link>
+ </th>
+ <th>
+ <Link href='/docs/general/dynamic-servers/host-bridge-networking'>
+ Host Network (Open Source & Enterprise)
+ </Link>
+ </th>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ <em>Requires single port</em>
+ </td>
+ <td>
+ <em>Requires port range</em>
+ </td>
+ </tr>
+ <tr>
+ <td>HTTPS / Secure WebSocket</td>
+ <td>✅</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>HTTP / WebSocket</td>
+ <td>✅</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>TCP + TLS</td>
+ <td>✅</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>TCP</td>
+ <td>✅</td>
+ <td>✅</td>
+ </tr>
+ <tr>
+ <td>UDP / WebRTC / ENet / KCP</td>
+ <td>✅</td>
+ <td>✅</td>
+ </tr>
+ </table>
+ );
}
export function InstallCli() {
- return (
- <Note>
- Make sure you have installed the Rivet CLI{" "}
- <Link
- href="https://github.com/rivet-gg/cli#installing"
- target="_blank"
- >
- here
- </Link>
- .
- </Note>
- );
+ return (
+ <Note>
+ Make sure you have installed the Rivet CLI{' '}
+ <Link href='https://github.com/rivet-gg/cli#installing' target='_blank'>
+ here
+ </Link>
+ .
+ </Note>
+ );
}
export function AutomateWithApi() {
- return (
- <Accordion title="Can I automate this with APIs?">
- <p>
- Rivet&apos;s Cloud API can be managed with your{" "}
- <Link href="/docs/general/concepts/token-types#cloud">
- cloud token
- </Link>
- . This is the same API we use internally and{" "}
- <Link href="https://github.com/rivet-gg/cli/blob/7f91d180f64b755956d89a3a83bfb2e77a42d72d/cli/src/commands/version.rs#L368">
- in the CLI
- </Link>
- .
- </p>
-
- <p>
- The Cloud REST API is documented{" "}
- <Link href="/docs/cloud">here</Link>. You can also use the{" "}
- <Link
- href="https://www.npmjs.com/package/@rivet-gg/api-full"
- target="_blank"
- >
- <code>@rivet-gg/api-full</code> NPM library
- </Link>{" "}
- to interact with the Cloud API.
- </p>
- </Accordion>
- );
+ return (
+ <Accordion title='Can I automate this with APIs?'>
+ <p>
+ Rivet&apos;s Cloud API can be managed with your{' '}
+ <Link href='/docs/general/concepts/token-types#cloud'>cloud token</Link>. This is the same API we use
+ internally and{' '}
+ <Link href='https://github.com/rivet-gg/cli/blob/7f91d180f64b755956d89a3a83bfb2e77a42d72d/cli/src/commands/version.rs#L368'>
+ in the CLI
+ </Link>
+ .
+ </p>
+
+ <p>
+ The Cloud REST API is documented <Link href='/docs/cloud'>here</Link>. You can also use the{' '}
+ <Link href='https://www.npmjs.com/package/@rivet-gg/api-full' target='_blank'>
+ <code>@rivet-gg/api-full</code> NPM library
+ </Link>{' '}
+ to interact with the Cloud API.
+ </p>
+ </Accordion>
+ );
}
export function CrashCourseUnrealBlueprint() {
- return null;
- return (
- <Tip>
- <p>TODO: Unreal crash blueprints course</p>
- <ul>
- <li>Comments</li>
- <li>3 ways to create nodes</li>
- </ul>
- </Tip>
- );
+ return null;
+ return (
+ <Tip>
+ <p>TODO: Unreal crash blueprints course</p>
+ <ul>
+ <li>Comments</li>
+ <li>3 ways to create nodes</li>
+ </ul>
+ </Tip>
+ );
Greptile
greptile
logic: Unreachable code in CrashCourseUnrealBlueprint: 'return null;' makes subsequent JSX unreachable. Remove one of the returns.
suggested fix
+export function CrashCourseUnrealBlueprint() {
return (
<Tip>
<p>TODO: Unreal crash blueprints course</p>
<ul>
<li>Comments</li>
<li>3 ways to create nodes</li>
</ul>
</Tip>
);
diff block
}
if (stage === PipelineStage.Transformation) {
- if (featureFlags[FEATURE_FLAGS.HOG_TRANSFORMATIONS]) {
- return <NewDestinations types={['transformation']} />
- }
+ return <NewDestinations types={['transformation']} />
return <TransformationOptionsTable />
Greptile
greptile
logic: Unreachable code: the second return statement will never be executed because it follows another return statement
suggested fix
+ return <TransformationOptionsTable />
diff block
+import {
+ showToast,
+ Toast,
+ getPreferenceValues,
+ Detail,
+ Icon,
+ Clipboard,
+ ActionPanel,
+ Action,
+ open,
+} from "@raycast/api";
+import { showFailureToast } from "@raycast/utils";
+import fs from "fs";
+import path from "path";
+import os from "os";
+import { promisify } from "util";
+import { exec } from "child_process";
+import { useEffect, useState, useRef } from "react";
+
+const execPromise = promisify(exec);
+
+interface Preferences {
+ outputFormat: "png" | "svg";
+ theme: "default" | "forest" | "dark" | "neutral";
+ savePath?: string;
+}
+
+// Image preview component
+function ImagePreview(props: { imagePath: string; format: string }) {
+ const { imagePath, format } = props;
+ const preferences = getPreferenceValues<Preferences>();
+
+ const [imageContent, setImageContent] = useState<string>("");
+ const [imageError, setImageError] = useState<string | null>(null);
+
+ useEffect(() => {
+ try {
+ if (format === "svg") {
+ setImageContent(fs.readFileSync(imagePath, "utf-8"));
+ } else {
+ const imageBuffer = fs.readFileSync(imagePath);
+ setImageContent(`data:image/png;base64,${imageBuffer.toString("base64")}`);
+ }
+ } catch (error) {
+ console.error("Failed to read image:", error);
+ const errorMessage = error instanceof Error ? error.message : String(error);
+ setImageError(`Unable to read image: ${errorMessage}`);
+ (async () => {
+ await showFailureToast({
+ title: "Failed to load image",
+ message: errorMessage,
+ });
+ })();
+ }
+ }, [imagePath, format]);
+
+ if (imageError) {
+ return <Detail markdown={`# Image loading failed\n\n${imageError}`} />;
+ }
+
+ const markdown = format === "svg" ? `<svg>${imageContent}</svg>` : `![Mermaid Diagram](${imageContent})`;
+
+ return (
+ <Detail
+ markdown={markdown}
+ actions={
+ <ActionPanel>
+ <Action
+ title="Copy Image"
+ icon={Icon.Clipboard}
+ shortcut={{ modifiers: ["cmd", "shift"], key: "c" }}
+ onAction={async () => {
+ try {
+ if (format === "svg") {
+ await Clipboard.copy(imageContent);
+ } else {
+ await execPromise(
+ `osascript -e 'set the clipboard to (read (POSIX file "${imagePath}") as TIFF picture)'`,
+ );
+ }
+ await showToast({
+ style: Toast.Style.Success,
+ title: "Image copied",
+ });
+ } catch (error) {
+ console.error("Copy error:", error);
+ await showFailureToast({
+ title: "Copy failed",
+ message: String(error),
+ });
+ }
+ }}
+ />
+ <Action
+ title="Save Image"
+ icon={Icon.SaveDocument}
+ shortcut={{ modifiers: ["cmd"], key: "s" }}
+ onAction={async () => {
+ try {
+ const customSavePath = preferences.savePath?.trim();
+ let saveDir = path.join(os.homedir(), "Downloads");
+ if (customSavePath && fs.existsSync(customSavePath)) {
+ saveDir = customSavePath;
+ }
+ const savedPath = path.join(saveDir, `mermaid-diagram-${Date.now()}.${format}`);
+ fs.copyFileSync(imagePath, savedPath);
+ await showToast({
+ style: Toast.Style.Success,
+ title: "Image saved",
+ message: `Saved to ${savedPath}`,
+ });
+ await open(path.dirname(savedPath));
+ } catch (error) {
+ await showFailureToast({
+ title: "Save failed",
+ message: String(error),
+ });
+ }
+ }}
+ />
+ <Action
+ title="Open in Default App"
+ icon={Icon.Eye}
+ shortcut={{ modifiers: ["cmd"], key: "o" }}
+ onAction={async () => {
+ try {
+ await open(imagePath);
+ } catch (error) {
+ await showFailureToast({
+ title: "Failed to open image",
+ message: String(error),
+ });
+ }
+ }}
+ />
+ </ActionPanel>
+ }
+ />
+ );
+}
+
+async function generateMermaidDiagram(mermaidCode: string, preferences: Preferences) {
+ let cleanCode = mermaidCode;
+ if (cleanCode.includes("```mermaid")) {
+ cleanCode = cleanCode.replace(/```mermaid\n/, "").replace(/```$/, "");
+ }
+
+ const tempFile = path.join(os.tmpdir(), `diagram-${Date.now()}.mmd`);
+ try {
+ fs.writeFileSync(tempFile, cleanCode);
+ } catch (error: unknown) {
+ console.error("Failed to write temporary file:", error);
+ throw new Error(`Failed to create temporary file: ${error instanceof Error ? error.message : String(error)}`);
+ }
+
+ const outputPath = path.join(os.tmpdir(), `diagram-${Date.now()}.${preferences.outputFormat}`);
+
+ console.log(`Generating diagram, theme: ${preferences.theme}, format: ${preferences.outputFormat}`);
+
+ const possiblePaths = ["/usr/local/bin/mmdc", "/opt/homebrew/bin/mmdc"];
+
+ let mmdcPath = "";
+ for (const p of possiblePaths) {
+ if (fs.existsSync(p)) {
+ mmdcPath = p;
+ break;
+ }
+ }
+
+ if (!mmdcPath) {
+ throw new Error("mermaid-cli (mmdc) command not found.");
+ }
+
+ const command = `"${mmdcPath}" -i "${tempFile}" -o "${outputPath}" -t ${preferences.theme} -b transparent --scale 2`;
+ const env = {
+ ...process.env,
+ NODE_OPTIONS: "--max-old-space-size=4096",
+ PATH: `/usr/local/bin:/opt/homebrew/bin:${process.env.PATH}`,
+ };
+
+ return await launchCommand(command, env, outputPath, tempFile);
+}
+
+async function launchCommand(
+ command: string,
+ env: NodeJS.ProcessEnv,
+ outputPath: string,
+ tempFile: string,
+): Promise<string> {
+ try {
+ await execPromise(command, { env, timeout: 10000 });
+
+ if (!fs.existsSync(outputPath)) {
+ throw new Error(`Diagram generation failed: Output file not found ${outputPath}`);
+ }
+
+ // Clean up temporary .mmd file
+ try {
+ if (fs.existsSync(tempFile)) {
+ fs.unlinkSync(tempFile);
+ console.log("Temporary file cleaned up after success:", tempFile);
+ }
+ } catch (cleanupError) {
+ console.error("Failed to clean up temporary file:", cleanupError);
+ }
+
+ return outputPath;
+ } catch (error: unknown) {
+ console.error("Command execution failed:", error);
+ // Clean up temporary files
+ try {
+ if (fs.existsSync(tempFile)) {
+ fs.unlinkSync(tempFile);
+ console.log("Temporary file cleaned up after error:", tempFile);
+ }
+ } catch (cleanupError) {
+ console.error("Failed to clean up temporary file:", cleanupError);
+ }
+ throw new Error(`Failed to generate diagram: ${error instanceof Error ? error.message : String(error)}`);
+ }
+
+ return outputPath;
Greptile
greptile
logic: Unreachable code - this return statement will never be executed since it's after the try/catch blocks that either return or throw
suggested fix
diff block
if (config.eventsToInclude) {
return config.eventsToInclude.split(',').map((e: string) => e.trim())
} else {
- return Object.keys(JSON.parse(config.eventEndpointMapping)).map((e: string) => e.trim())
+ return Object.keys(parseJSON(config.eventEndpointMapping)).map((e: string) => e.trim())
}
return []
Greptile
greptile
logic: Unreachable code - this return statement will never be executed due to the if-else block above
suggested fix
+ if (config.eventsToInclude) {
+ return config.eventsToInclude.split(',').map((e: string) => e.trim())
+ } else {
return Object.keys(parseJSON(config.eventEndpointMapping)).map((e: string) => e.trim())
+ }
diff block
for result in returned_results:
if isinstance(result, list):
final_result.extend(result)
- elif isinstance(result, dict):
+ elif isinstance(result, dict): # type: ignore [unreachable]
Greptile
greptile
style: Type ignore comment added for unreachable code - consider removing the entire elif branch if it's truly unreachable
suggested fix
+ # This case is unreachable since we check for lists above
+ final_result.extend(result)
diff block
//
-// Model+Input.swift
+// OnitPanelState+Input.swift
// Onit
//
// Created by Benjamin Sage on 10/3/24.
//
import AppKit
+import Defaults
-extension OnitModel {
+extension OnitPanelState {
func addAutoContext() {
- guard FeatureFlagManager.shared.accessibility,
- FeatureFlagManager.shared.accessibilityAutoContext
+ guard Defaults[.autoContextEnabled],
+ Defaults[.autoContextFromCurrentWindow]
else {
return
}
let appName = AccessibilityNotificationsManager.shared.screenResult.applicationName ?? "AutoContext"
if let errorMessage = AccessibilityNotificationsManager.shared.screenResult.errorMessage {
- let errorContext = Context(appName: "Unable to add \(appName)", appContent: ["error": errorMessage])
+ let errorContext = Context(appName: "Unable to add \(appName)", appHash: 0, appTitle: "", appContent: ["error": errorMessage])
pendingContextList.insert(errorContext, at: 0)
return
}
guard let appContent = AccessibilityNotificationsManager.shared.screenResult.others else {
- let errorContext = Context(appName: "Unable to add \(appName)", appContent: ["error": "Empty text"])
+ let errorContext = Context(appName: "Unable to add \(appName)", appHash: 0, appTitle: "", appContent: ["error": "Empty text"])
pendingContextList.insert(errorContext, at: 0)
return
}
-
- /** Prevent duplication */
- let contextDuplicated = pendingContextList.contains { context in
- if case .auto(let contextApp, let contextContent) = context {
- return contextApp == appName && contextContent == appContent
+ guard let activeTrackedWindow = AccessibilityNotificationsManager.shared.windowsManager.activeTrackedWindow else {
+ let errorContext = Context(appName: "Unable to add \(appName)", appHash: 0, appTitle: "", appContent: ["error": "Cannot identify context"])
+ pendingContextList.insert(errorContext, at: 0)
+ return
+ }
+ let appHash = CFHash(activeTrackedWindow.element)
+ let appTitle = activeTrackedWindow.title
+
+ log.error("")
+ if let existingIndex = pendingContextList.firstIndex(where: { context in
+ if case .auto(let autoContext) = context {
+ log.error("Searching lhs: \(autoContext.appName) \(autoContext.appHash) \(autoContext.appTitle)")
+ log.error("Searching rhs: \(appName) \(appHash) \(appTitle)")
+ return autoContext.appName == appName && autoContext.appHash == appHash && autoContext.appTitle == appTitle
}
return false
- }
- guard !contextDuplicated else {
- // TODO: KNA - Notify user for duplicated context
+ }) {
+ log.error("Found existing auto context")
+ /// For now, we're simply replacing the context.
+ /// Later on, we should implement a data aggregator.
+ let autoContext = Context(appName: appName, appHash: appHash, appTitle: appTitle, appContent: appContent)
+ pendingContextList[existingIndex] = autoContext
+
return
Greptile
greptile
logic: unreachable code after return statement - commented merge functionality should be removed or uncommented
diff block
db_session: Session = Depends(get_session),
) -> CreateChatSessionID:
user_id = user.id if user is not None else None
+
+ try:
+ # Check if the persona exists and is valid for this user.
+ # An exception will be thrown if the persona is not valid.
+ persona = get_persona_by_id(
+ persona_id=chat_session_creation_request.persona_id,
+ user=user,
+ db_session=db_session,
+ is_for_edit=False,
+ )
+
+ # Ensure the persona is visible
+ if not persona.is_visible:
+ raise Exception("Persona is not visible to the user.")
+
+ except Exception as e:
+ logger.exception(e)
+ raise HTTPException(
+ status_code=400,
+ detail="The given user does not have access to this Persona.",
+ )
+ return
Greptile
greptile
logic: Unreachable code after HTTPException - remove return statement
suggested fix
)
diff block
import { supabaseAuth } from "../supabase";
export class SupabaseService implements AuthService {
- private static instance: SupabaseService;
-
- static getInstance(): SupabaseService {
- if (!SupabaseService.instance) {
- SupabaseService.instance = new SupabaseService();
- }
- return SupabaseService.instance;
- }
-
- async signIn(email: string, password: string): Promise<any> {
- try {
- const { error } = await supabaseAuth.signInWithPassword(email, password);
- return { error };
- } catch (error) {
- console.error("Error in Supabase signIn:", error);
- return { error };
- }
+ private static instance: SupabaseService;
+
+ static getInstance(): SupabaseService {
+ if (!SupabaseService.instance) {
+ SupabaseService.instance = new SupabaseService();
}
- async signOut(): Promise<any> {
- const { error } = await supabaseAuth.signOut();
- return error;
+ return SupabaseService.instance;
+ }
+
+ async signIn(email: string, password: string): Promise<any> {
+ try {
+ const { error } = await supabaseAuth.signInWithPassword(email, password);
+ return { error };
+ } catch (error) {
+ console.error("Error in Supabase signIn:", error);
+ return { error };
}
- async signUp(email: string, password: string, options?: any): Promise<any> {
- const { error } = await supabaseAuth.signUp(email, password, options);
- if (error) {
- throw error;
- }
+ }
+ async signOut(): Promise<any> {
+ const { error } = await supabaseAuth.signOut();
+ return error;
+ }
+ async signUp(email: string, password: string, options?: any): Promise<any> {
+ const { data, error } = await supabaseAuth.signUp(email, password, options);
+ console.log("========+++++++==========>", data);
+ if (error) {
+ throw error;
}
+ }
- async getCurrentUser(): Promise<any | null> {
- const { data, error } = await supabaseAuth.getUser();
- if (error) {
- throw error;
- }
- return data.user;
+ async getCurrentUser(): Promise<any | null> {
+ const { data, error } = await supabaseAuth.getUser();
+ if (error) {
+ throw error;
}
+ return data.user;
+ }
- async signInWithCredentials(credentials: any): Promise<any> {
- const { error } = await supabaseAuth.signInWithPassword(credentials.email, credentials.password);
- if (error) {
- throw error;
- }
- return error;
+ async signInWithCredentials(credentials: any): Promise<any> {
+ const { error } = await supabaseAuth.signInWithPassword(
+ credentials.email,
+ credentials.password
+ );
+ if (error) {
+ throw error;
}
-
- async signInWithOAuth(provider: any, options?: any): Promise<any> {
- const { data, error } = await supabaseAuth.signInWithOAuth(provider, options);
- if (error) {
- throw error;
- }
- return data;
+ return error;
+ }
Greptile
greptile
logic: signInWithCredentials throws error then returns it - this is unreachable code. Should either throw or return.
suggested fix
async signInWithCredentials(credentials: any): Promise<any> {
+ const { data, error } = await supabaseAuth.signInWithPassword(
credentials.email,
credentials.password
);
if (error) {
throw error;
}
+ return data;
}
diff block
const query = c.req.query("code");
const exitCode = query ? Number(query) : 0;
- if (typeof Deno != "undefined") Deno.exit(exitCode);
- else process.exit(exitCode);
+ process.exit(exitCode);
return c.text("unreachable");
Greptile
greptile
style: unreachable code after process.exit() should be removed
diff block
+import axios, { AxiosInstance } from "axios";
+import type { AllDebridUser } from "@types";
+import { logger } from "@main/services";
+
+interface AllDebridMagnetStatus {
+ id: number;
+ filename: string;
+ size: number;
+ status: string;
+ statusCode: number;
+ downloaded: number;
+ uploaded: number;
+ seeders: number;
+ downloadSpeed: number;
+ uploadSpeed: number;
+ uploadDate: number;
+ completionDate: number;
+ links: Array<{
+ link: string;
+ filename: string;
+ size: number;
+ }>;
+}
+
+interface AllDebridError {
+ code: string;
+ message: string;
+}
+
+interface AllDebridDownloadUrl {
+ link: string;
+ size?: number;
+ filename?: string;
+}
+
+export class AllDebridClient {
+ private static instance: AxiosInstance;
+ private static readonly baseURL = "https://api.alldebrid.com/v4";
+
+ static authorize(apiKey: string) {
+ logger.info("[AllDebrid] Authorizing with key:", apiKey ? "***" : "empty");
+ this.instance = axios.create({
+ baseURL: this.baseURL,
+ params: {
+ agent: "hydra",
+ apikey: apiKey,
+ },
+ });
+ }
+
+ static async getUser() {
+ try {
+ const response = await this.instance.get<{
+ status: string;
+ data?: { user: AllDebridUser };
+ error?: AllDebridError;
+ }>("/user");
+
+ logger.info("[AllDebrid] API Response:", response.data);
+
+ if (response.data.status === "error") {
+ const error = response.data.error;
+ logger.error("[AllDebrid] API Error:", error);
+ if (error?.code === "AUTH_MISSING_APIKEY") {
+ return { error_code: "alldebrid_missing_key" };
+ }
+ if (error?.code === "AUTH_BAD_APIKEY") {
+ return { error_code: "alldebrid_invalid_key" };
+ }
+ if (error?.code === "AUTH_BLOCKED") {
+ return { error_code: "alldebrid_blocked" };
+ }
+ if (error?.code === "AUTH_USER_BANNED") {
+ return { error_code: "alldebrid_banned" };
+ }
+ return { error_code: "alldebrid_unknown_error" };
+ }
+
+ if (!response.data.data?.user) {
+ logger.error("[AllDebrid] No user data in response");
+ return { error_code: "alldebrid_invalid_response" };
+ }
+
+ logger.info(
+ "[AllDebrid] Successfully got user:",
+ response.data.data.user.username
+ );
+ return { user: response.data.data.user };
+ } catch (error: any) {
+ logger.error("[AllDebrid] Request Error:", error);
+ if (error.response?.data?.error) {
+ return { error_code: "alldebrid_invalid_key" };
+ }
+ return { error_code: "alldebrid_network_error" };
+ }
+ }
+
+ private static async uploadMagnet(magnet: string) {
+ try {
+ logger.info("[AllDebrid] Uploading magnet with params:", { magnet });
+
+ const response = await this.instance.get("/magnet/upload", {
+ params: {
+ magnets: [magnet],
+ },
+ });
+
+ logger.info(
+ "[AllDebrid] Upload Magnet Raw Response:",
+ JSON.stringify(response.data, null, 2)
+ );
+
+ if (response.data.status === "error") {
+ throw new Error(response.data.error?.message || "Unknown error");
+ }
+
+ const magnetInfo = response.data.data.magnets[0];
+ logger.info(
+ "[AllDebrid] Magnet Info:",
+ JSON.stringify(magnetInfo, null, 2)
+ );
+
+ if (magnetInfo.error) {
+ throw new Error(magnetInfo.error.message);
+ }
+
+ return magnetInfo.id;
+ } catch (error: any) {
+ logger.error("[AllDebrid] Upload Magnet Error:", error);
+ throw error;
+ }
+ }
+
+ private static async checkMagnetStatus(
+ magnetId: number
+ ): Promise<AllDebridMagnetStatus> {
+ try {
+ logger.info("[AllDebrid] Checking magnet status for ID:", magnetId);
+
+ const response = await this.instance.get(`/magnet/status`, {
+ params: {
+ id: magnetId,
+ },
+ });
+
+ logger.info(
+ "[AllDebrid] Check Magnet Status Raw Response:",
+ JSON.stringify(response.data, null, 2)
+ );
+
+ if (!response.data) {
+ throw new Error("No response data received");
+ }
+
+ if (response.data.status === "error") {
+ throw new Error(response.data.error?.message || "Unknown error");
+ }
+
+ // Verificăm noua structură a răspunsului
+ const magnetData = response.data.data?.magnets;
+ if (!magnetData || typeof magnetData !== "object") {
+ logger.error(
+ "[AllDebrid] Invalid response structure:",
+ JSON.stringify(response.data, null, 2)
+ );
+ throw new Error("Invalid magnet status response format");
+ }
+
+ // Convertim răspunsul în formatul așteptat
+ const magnetStatus: AllDebridMagnetStatus = {
+ id: magnetData.id,
+ filename: magnetData.filename,
+ size: magnetData.size,
+ status: magnetData.status,
+ statusCode: magnetData.statusCode,
+ downloaded: magnetData.downloaded,
+ uploaded: magnetData.uploaded,
+ seeders: magnetData.seeders,
+ downloadSpeed: magnetData.downloadSpeed,
+ uploadSpeed: magnetData.uploadSpeed,
+ uploadDate: magnetData.uploadDate,
+ completionDate: magnetData.completionDate,
+ links: magnetData.links.map((link) => ({
+ link: link.link,
+ filename: link.filename,
+ size: link.size,
+ })),
+ };
+
+ logger.info(
+ "[AllDebrid] Magnet Status:",
+ JSON.stringify(magnetStatus, null, 2)
+ );
+
+ return magnetStatus;
+ } catch (error: any) {
+ logger.error("[AllDebrid] Check Magnet Status Error:", error);
+ throw error;
+ }
+ }
+
+ private static async unlockLink(link: string) {
+ try {
+ const response = await this.instance.get<{
+ status: string;
+ data?: { link: string };
+ error?: AllDebridError;
+ }>("/link/unlock", {
+ params: {
+ link,
+ },
+ });
+
+ if (response.data.status === "error") {
+ throw new Error(response.data.error?.message || "Unknown error");
+ }
+
+ const unlockedLink = response.data.data?.link;
+ if (!unlockedLink) {
+ throw new Error("No download link received from AllDebrid");
+ }
+
+ return unlockedLink;
+ } catch (error: any) {
+ logger.error("[AllDebrid] Unlock Link Error:", error);
+ throw error;
+ }
+ }
+
+ public static async getDownloadUrls(
+ uri: string
+ ): Promise<AllDebridDownloadUrl[]> {
+ try {
+ logger.info("[AllDebrid] Getting download URLs for URI:", uri);
+
+ if (uri.startsWith("magnet:")) {
+ logger.info("[AllDebrid] Detected magnet link, uploading...");
+ // 1. Upload magnet
+ const magnetId = await this.uploadMagnet(uri);
+ logger.info("[AllDebrid] Magnet uploaded, ID:", magnetId);
+
+ // 2. Verificăm statusul până când avem link-uri
+ let retries = 0;
+ let magnetStatus: AllDebridMagnetStatus;
+
+ do {
+ magnetStatus = await this.checkMagnetStatus(magnetId);
+ logger.info(
+ "[AllDebrid] Magnet status:",
+ magnetStatus.status,
+ "statusCode:",
+ magnetStatus.statusCode
+ );
+
+ if (magnetStatus.statusCode === 4) {
+ // Ready
+ // Deblocăm fiecare link în parte și aruncăm eroare dacă oricare eșuează
+ const unlockedLinks = await Promise.all(
+ magnetStatus.links.map(async (link) => {
+ try {
+ const unlockedLink = await this.unlockLink(link.link);
+ logger.info(
+ "[AllDebrid] Successfully unlocked link:",
+ unlockedLink
+ );
+ return {
+ link: unlockedLink,
+ size: link.size,
+ filename: link.filename,
+ };
+ } catch (error) {
+ logger.error(
+ "[AllDebrid] Failed to unlock link:",
+ link.link,
+ error
+ );
+ throw new Error("Failed to unlock all links");
+ }
+ })
+ );
+
+ logger.info(
+ "[AllDebrid] Got unlocked download links:",
+ unlockedLinks
+ );
+ return unlockedLinks;
+ }
+
+ if (retries++ > 30) {
+ // Maximum 30 de încercări
+ throw new Error("Timeout waiting for magnet to be ready");
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 2000)); // Așteptăm 2 secunde între verificări
+ } while (magnetStatus.statusCode !== 4);
+ } else {
+ logger.info("[AllDebrid] Regular link, unlocking...");
+ // Pentru link-uri normale, doar debridam link-ul
+ const downloadUrl = await this.unlockLink(uri);
+ logger.info("[AllDebrid] Got unlocked download URL:", downloadUrl);
+ return [
+ {
+ link: downloadUrl,
+ },
+ ];
+ }
+ } catch (error: any) {
+ logger.error("[AllDebrid] Get Download URLs Error:", error);
+ throw error;
+ }
+ return []; // Add default return for TypeScript
Greptile
greptile
logic: This default return [] is unreachable code since all code paths above either return a value or throw an error. It should be removed.
suggested fix
diff block
-posthog/warehouse/models/ssh_tunnel.py:0: error: Incompatible types in assignment (expression has type "NoEncryption", variable has type "BestAvailableEncryption") [assignment]
posthog/temporal/data_imports/pipelines/sql_database/schema_types.py:0: error: Statement is unreachable [unreachable]
posthog/temporal/data_imports/pipelines/sql_database/schema_types.py:0: error: Non-overlapping equality check (left operand type: "Literal['text', 'double', 'bool', 'timestamp', 'bigint', 'json', 'decimal', 'wei', 'date', 'time'] | None", right operand type: "Literal['interval']") [comparison-overlap]
Greptile
greptile
style: Unreachable code and non-overlapping equality check in schema_types.py indicate potential logical errors
diff block
async start(ctx) {
console.log(ctx);
- await ctx.kv.putBatch(new Map([[['foob', 'b'], 12], [['foob', 'a'], null], [['foob', 'c'], true]]));
+ await ctx.kv.putBatch(
+ new Map([
+ [["foob", "b"], 12],
+ [["foob", "a"], null],
+ [["foob", "c"], true],
+ ]),
+ );
- let res = await ctx.kv.list({ prefix: ['foob'] });
+ const res = await ctx.kv.list({ prefix: ["foob"] });
console.log(res.array(), res.raw(), res.entries());
- console.log(res.get(['foob', 'b']));
+ console.log(res.get(["foob", "b"]));
Deno.exit(2);
- throw new Error('bingus');
- }
+ throw new Error("bingus");
Greptile
greptile
logic: Unreachable code after Deno.exit(2). The Error will never be thrown.
diff block
+package testscenario
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+
+ "github.com/amp-labs/connectors"
+ "github.com/amp-labs/connectors/common"
+ "github.com/amp-labs/connectors/internal/datautils"
+ "github.com/amp-labs/connectors/test/utils"
+ "github.com/amp-labs/connectors/test/utils/mockutils"
+)
+
+type ConnectorCRUD interface {
+ connectors.ReadConnector
+ connectors.WriteConnector
+ connectors.DeleteConnector
+}
+
+type CRUDTestSuite struct {
+ ReadFields datautils.StringSet
+ SearchBy Property
+ RecordIdentifierKey string
+ UpdatedFields map[string]string
+}
+
+type Property struct {
+ Key string
+ Value string
+}
+
+func ValidateCreateUpdateDelete[CP, UP any](ctx context.Context, conn ConnectorCRUD, objectName string,
+ createPayload CP, updatePayload UP, suite CRUDTestSuite,
+) {
+ fmt.Println("> TEST Create/Update/Delete", objectName)
+ fmt.Println("Creating", objectName)
+ createObject(ctx, conn, objectName, &createPayload)
+
+ fmt.Println("Reading", objectName)
+
+ res := readObjects(ctx, conn, objectName, suite.ReadFields)
+
+ fmt.Println("Finding recently created", objectName)
+
+ search := suite.SearchBy
+ object := searchObject(res, search.Key, search.Value)
+ objectID := getRecordIdentifierValue(object, suite.RecordIdentifierKey)
+
+ fmt.Println("Updating some object properties")
+ updateObject(ctx, conn, objectName, objectID, &updatePayload)
+ fmt.Println("Validate object has changed accordingly")
+
+ res = readObjects(ctx, conn, objectName, suite.ReadFields)
+
+ object = searchObject(res, suite.RecordIdentifierKey, objectID)
+ for k, v := range suite.UpdatedFields {
+ if !mockutils.DoesObjectCorrespondToString(object[k], v) {
+ utils.Fail("error updated properties do not match", k, v, object[k])
+ }
+ }
+
+ fmt.Println("Removing this", objectName)
+ removeObject(ctx, conn, objectName, objectID)
+ fmt.Println("> Successful test completion")
+}
+
+func getRecordIdentifierValue(object map[string]any, key string) string {
+ switch id := object[key].(type) {
+ case string:
+ return id
+ case float64:
+ return strconv.FormatFloat(id, 'f', -1, 64)
+ case int64:
+ return strconv.FormatInt(id, 10)
+ default:
+ return fmt.Sprintf("%v", id)
+ }
+}
+
+func createObject[CP any](ctx context.Context, conn ConnectorCRUD, objectName string, payload *CP) {
+ res, err := conn.Write(ctx, common.WriteParams{
+ ObjectName: objectName,
+ RecordId: "",
+ RecordData: payload,
+ })
+ if err != nil {
+ utils.Fail("error creating an object", "error", err)
+ }
+
+ if !res.Success {
+ utils.Fail("failed to create an object")
+ }
+}
+
+func readObjects(ctx context.Context, conn ConnectorCRUD, objectName string, fields datautils.StringSet) *common.ReadResult {
+ res, err := conn.Read(ctx, common.ReadParams{
+ ObjectName: objectName,
+ Fields: fields,
+ })
+ if err != nil {
+ utils.Fail("error reading from provider", "error", err)
+ }
+
+ return res
+}
+
+func searchObject(res *common.ReadResult, key, value string) map[string]any {
+ for _, data := range res.Data {
+ if mockutils.DoesObjectCorrespondToString(data.Fields[key], value) {
+ return data.Fields
+ }
+ }
+
+ utils.Fail("error finding object in a list")
+
+ return nil
+}
Greptile
greptile
style: searchObject returns nil after utils.Fail which is unreachable code. Remove the return nil statement.
suggested fix
func searchObject(res *common.ReadResult, key, value string) map[string]any {
 	for _, data := range res.Data {
 		if mockutils.DoesObjectCorrespondToString(data.Fields[key], value) {
 			return data.Fields
 		}
 	}

 	utils.Fail("error finding object in a list")
 }
diff block
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
+ "composite": true,
+ "tsBuildInfoFile": "./.tsbuildinfo",
+ "noErrorTruncation": false,
+ "importsNotUsedAsValues": "remove",
+ "disableSizeLimit": true,
+ "allowUnreachableCode": true,
+ "allowUnusedLabels": true,
Greptile
greptile
logic: Allowing unreachable code and unused labels disables important code quality checks that help catch bugs. Consider keeping these disabled unless there's a specific need.
suggested fix
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
diff block
let handleAliases: string[];
switch (connectedAccount.provider) {
- case 'microsoft':
+ case ConnectedAccountProvider.MICROSOFT:
handleAliases =
await this.microsoftEmailAliasManagerService.getHandleAliases(
connectedAccount,
);
break;
- case 'google':
+ case ConnectedAccountProvider.GOOGLE:
handleAliases =
await this.googleEmailAliasManagerService.getHandleAliases(
connectedAccount,
);
break;
default:
- throw new Error(
+ assertUnreachable(
+ connectedAccount.provider,
`Email alias manager for provider ${connectedAccount.provider} is not implemented`,
);
}
Greptile
greptile
logic: handleAliases will be undefined after assertUnreachable throws. Add a return or throw after assertUnreachable to satisfy TypeScript and prevent potential runtime issues. ```suggestion + let handleAliases: string[]; + switch (connectedAccount.provider) { case ConnectedAccountProvider.MICROSOFT: + handleAliases = + await this.microsoftEmailAliasManagerService.getHandleAliases( + connectedAccount, + ); + break; case ConnectedAccountProvider.GOOGLE: + handleAliases = + await this.googleEmailAliasManagerService.getHandleAliases( + connectedAccount, + ); + break; + default: assertUnreachable( connectedAccount.provider, + `Email alias manager for provider ${connectedAccount.provider} is not implemented`, + ); + throw new Error('Unreachable code'); + } ```
diff block
+import { BindLogic, useValues } from 'kea'
+import { useState } from 'react'
+import { InsightLoadingState } from 'scenes/insights/EmptyStates'
+import { insightLogic } from 'scenes/insights/insightLogic'
+import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic'
+import { LineGraph } from 'scenes/insights/views/LineGraph/LineGraph'
+
+import { dataNodeLogic } from '~/queries/nodes/DataNode/dataNodeLogic'
+import {
+ AnyResponseType,
+ RevenueAnalyticsGrowthRateQuery,
+ RevenueAnalyticsGrowthRateQueryResponse,
+} from '~/queries/schema/schema-general'
+import { QueryContext } from '~/queries/types'
+import { GraphDataset, GraphType } from '~/types'
+
+let uniqueNode = 0
+export function RevenueAnalyticsGrowthRateNode(props: {
+ query: RevenueAnalyticsGrowthRateQuery
+ cachedResults?: AnyResponseType
+ context: QueryContext
+}): JSX.Element | null {
+ const { onData, loadPriority, dataNodeCollectionId } = props.context.insightProps ?? {}
+ const [key] = useState(() => `RevenueAnalyticsGrowthRate.${uniqueNode++}`)
+ const logic = dataNodeLogic({
+ query: props.query,
+ key,
+ cachedResults: props.cachedResults,
+ loadPriority,
+ onData,
+ dataNodeCollectionId: dataNodeCollectionId ?? key,
+ })
+
+ const { response, responseLoading, queryId } = useValues(logic)
+
+ // TODO: Figure out what `insightProps` should be
+ if (responseLoading) {
+ return <InsightLoadingState queryId={queryId} key={queryId} insightProps={props.context.insightProps ?? {}} />
+ }
+
+ // `results` is an array of array in order [month, mrr, previous_mrr, growth_rate, 3m_growth_rate, 6m_growth_rate]
+ const queryResponse = response as RevenueAnalyticsGrowthRateQueryResponse | undefined
+
+ // Remove first entry, it won't have any growth information
+ const results = ((queryResponse?.results ?? []) as any[][]).slice(1)
+
+ const labels: string[] = Array.from(new Set(results.map((result) => result[0]))).sort() as string[]
+ const datasets: (GraphDataset & { colorIndex: number })[] = [
+ {
+ id: 1,
+ label: 'Growth Rate',
+ data: results.map((result) => result[3] * 100),
+ colorIndex: 0,
+ },
+ {
+ id: 2,
+ label: '3 Month Growth Rate',
+ data: results.map((result) => result[4] * 100),
+ colorIndex: 1,
+ },
+ {
+ id: 3,
+ label: '6 Month Growth Rate',
+ data: results.map((result) => result[5] * 100),
+ colorIndex: 2,
+ },
+ ]
+
+ return (
+ <div className="InsightVizDisplay InsightVizDisplay--type-trends border rounded bg-surface-primary">
+ <div className="InsightVizDisplay__content">
+ <BindLogic logic={insightLogic} props={props.context.insightProps ?? {}}>
+ <BindLogic logic={insightVizDataLogic} props={props.context.insightProps ?? {}}>
+ <LineGraph
+ data-attr="revenue-analytics-top-customers-node-graph"
+ type={GraphType.Line}
+ datasets={datasets}
+ labels={labels}
+ trendsFilter={{ aggregationAxisFormat: 'percentage' }}
+ labelGroupType="none"
+ />
+ </BindLogic>
+ </BindLogic>
+ </div>
+ </div>
+ )
+
+ return <div>{JSON.stringify({ response, responseLoading })}</div>
+
+ // const results = responseLoading ? range(NUM_SKELETONS).map(() => undefined) : queryResponse?.results ?? []
+
+ // return (
+ // <div className="grid auto-cols-fr grid-flow-col w-full gap-2">
+ // {results.map((item, index) => (
+ // <div key={item?.key ?? index} className={cn(HEIGHT_CLASS, { [REVENUE_CONTAINER_CLASS]: index === 0 })}>
+ // <ItemCell item={item} />
+ // </div>
+ // ))}
+ // </div>
+ // )
Greptile
greptile
logic: unreachable code after the first return statement - this should be removed
suggested fix
diff block
+import sanitizeHtml from "sanitize-html";
+
+import { Kind } from "./api/fabricClient";
+
+export function removeHtml(html: string) {
+ return sanitizeHtml(html, {
+ allowedTags: [],
+ allowedAttributes: {},
+ textFilter: (text) => " " + text.slice(0, 1000),
+ });
+}
+
+export function getKindIcon(kind: Kind | null) {
+ // This automatically applies the dark mode.
+ const tintColor = {
+ dark: "#ffffff",
+ light: "#000000",
+ };
+
+ switch (kind) {
+ case Kind.DEFAULT_FILE:
+ return {
+ source: "icons/kind/file.svg",
+ tintColor,
+ };
+ break;
Greptile
greptile
logic: Unreachable code after return statement
suggested fix
return {
         source: "icons/kind/file.svg",
         tintColor,
       };
diff block
+import sanitizeHtml from "sanitize-html";
+
+import { Kind } from "./api/fabricClient";
+
+export function removeHtml(html: string) {
+ return sanitizeHtml(html, {
+ allowedTags: [],
+ allowedAttributes: {},
+ textFilter: (text) => " " + text.slice(0, 1000),
+ });
+}
+
+export function getKindIcon(kind: Kind | null) {
+ // This automatically applies the dark mode.
+ const tintColor = {
+ dark: "#ffffff",
+ light: "#000000",
+ };
+
+ switch (kind) {
+ case Kind.DEFAULT_FILE:
+ return {
+ source: "icons/kind/file.svg",
+ tintColor,
+ };
+ break;
+ case null:
+ return {
+ source: "icons/kind/all.svg",
+ tintColor,
+ };
+ break;
Greptile
greptile
logic: Unreachable code after return statement
suggested fix
return {
         source: "icons/kind/all.svg",
         tintColor,
       };