@@ -39,23 +39,34 @@ import {
3939} from "react" ;
4040import { useHydrated } from "remix-utils/use-hydrated" ;
4141import { PageHeader } from "~/commonComponents/PageHeader/PageHeader" ;
42+ import {
43+ NimbusAwaitErrorElement ,
44+ NimbusDefaultRouteErrorBoundary ,
45+ } from "cyberstorm/utils/errors/NimbusErrorBoundary" ;
4246import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons" ;
4347import { RelativeTime } from "@thunderstore/cyberstorm/src/components/RelativeTime/RelativeTime" ;
4448import {
4549 formatFileSize ,
4650 formatInteger ,
4751 formatToDisplayName ,
4852} from "@thunderstore/cyberstorm/src/utils/utils" ;
49- import { DapperTs } from "@thunderstore/dapper-ts" ;
5053import { type OutletContextShape } from "~/root" ;
5154import { CopyButton } from "~/commonComponents/CopyButton/CopyButton" ;
52- import {
53- getPublicEnvVariables ,
54- getSessionTools ,
55- } from "cyberstorm/security/publicEnvVariables" ;
55+ import { getPublicEnvVariables } from "cyberstorm/security/publicEnvVariables" ;
5656import { getTeamDetails } from "@thunderstore/dapper-ts/src/methods/team" ;
5757import { isPromise } from "cyberstorm/utils/typeChecks" ;
5858import { getPackageVersionDetails } from "@thunderstore/dapper-ts/src/methods/packageVersion" ;
59+ import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
60+ import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError" ;
61+ import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings" ;
62+ import { getLoaderTools } from "cyberstorm/utils/getLoaderTools" ;
63+
64+ const packageVersionNotFoundMappings = [
65+ createNotFoundMapping (
66+ "Package version not found." ,
67+ "We could not find the requested package version."
68+ ) ,
69+ ] ;
5970
6071export async function loader ( { params } : LoaderFunctionArgs ) {
6172 if (
@@ -64,55 +75,81 @@ export async function loader({ params }: LoaderFunctionArgs) {
6475 params . packageId &&
6576 params . packageVersion
6677 ) {
67- const publicEnvVariables = getPublicEnvVariables ( [ "VITE_API_URL" ] ) ;
68- const dapper = new DapperTs ( ( ) => {
78+ const { dapper } = getLoaderTools ( ) ;
79+ try {
80+ const [ community , version , team ] = await Promise . all ( [
81+ dapper . getCommunity ( params . communityId ) ,
82+ dapper . getPackageVersionDetails (
83+ params . namespaceId ,
84+ params . packageId ,
85+ params . packageVersion
86+ ) ,
87+ dapper . getTeamDetails ( params . namespaceId ) ,
88+ ] ) ;
89+
6990 return {
70- apiHost : publicEnvVariables . VITE_API_URL ,
71- sessionId : undefined ,
91+ communityId : params . communityId ,
92+ community,
93+ version,
94+ team,
7295 } ;
73- } ) ;
74-
75- return {
76- communityId : params . communityId ,
77- community : await dapper . getCommunity ( params . communityId ) ,
78- version : await dapper . getPackageVersionDetails (
79- params . namespaceId ,
80- params . packageId ,
81- params . packageVersion
82- ) ,
83- team : await dapper . getTeamDetails ( params . namespaceId ) ,
84- } ;
96+ } catch ( error ) {
97+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } ) ;
98+ }
8599 }
86- throw new Response ( "Package not found" , { status : 404 } ) ;
100+ throwUserFacingPayloadResponse ( {
101+ headline : "Package not found." ,
102+ description : "We could not find the requested package." ,
103+ category : "not_found" ,
104+ status : 404 ,
105+ } ) ;
87106}
88107
89- export async function clientLoader ( { params } : LoaderFunctionArgs ) {
108+ export function clientLoader ( { params } : LoaderFunctionArgs ) {
90109 if (
91110 params . communityId &&
92111 params . namespaceId &&
93112 params . packageId &&
94113 params . packageVersion
95114 ) {
96- const tools = getSessionTools ( ) ;
97- const dapper = new DapperTs ( ( ) => {
98- return {
99- apiHost : tools ?. getConfig ( ) . apiHost ,
100- sessionId : tools ?. getConfig ( ) . sessionId ,
101- } ;
102- } ) ;
103-
104- return {
105- communityId : params . communityId ,
106- community : dapper . getCommunity ( params . communityId ) ,
107- version : dapper . getPackageVersionDetails (
115+ const { dapper } = getLoaderTools ( ) ;
116+ const community = dapper
117+ . getCommunity ( params . communityId )
118+ . catch ( ( error ) =>
119+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
120+ ) ;
121+ const version = dapper
122+ . getPackageVersionDetails (
108123 params . namespaceId ,
109124 params . packageId ,
110125 params . packageVersion
111- ) ,
112- team : dapper . getTeamDetails ( params . namespaceId ) ,
126+ )
127+ . catch ( ( error ) =>
128+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
129+ ) ;
130+ const team = dapper
131+ . getTeamDetails ( params . namespaceId )
132+ . catch ( ( error ) =>
133+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
134+ ) ;
135+
136+ return {
137+ communityId : params . communityId ,
138+ community,
139+ version,
140+ team,
113141 } ;
114142 }
115- throw new Response ( "Package not found" , { status : 404 } ) ;
143+ throwUserFacingPayloadResponse ( {
144+ headline : "Package not found." ,
145+ description : "We could not find the requested package." ,
146+ category : "not_found" ,
147+ status : 404 ,
148+ } ) ;
149+ }
150+
151+ export function ErrorBoundary ( ) {
152+ return < NimbusDefaultRouteErrorBoundary /> ;
116153}
117154
118155export function shouldRevalidate ( arg : ShouldRevalidateFunctionArgs ) {
@@ -152,39 +189,65 @@ export default function PackageVersion() {
152189 // If strict mode is removed from the entry.client.tsx, this should only run once
153190 useEffect ( ( ) => {
154191 if ( ! startsHydrated . current && isHydrated ) return ;
155- if ( isPromise ( version ) ) {
156- version . then ( ( versionData ) => {
157- setFirstUploaded (
158- < RelativeTime
159- time = { versionData . datetime_created }
160- suppressHydrationWarning
161- />
162- ) ;
163- } ) ;
164- } else {
192+ if ( ! isPromise ( version ) ) {
165193 setFirstUploaded (
166194 < RelativeTime
167195 time = { version . datetime_created }
168196 suppressHydrationWarning
169197 />
170198 ) ;
199+ return ;
171200 }
172- } , [ ] ) ;
201+
202+ let isCancelled = false ;
203+
204+ const resolveVersionTimes = async ( ) => {
205+ try {
206+ const versionData = await version ;
207+ if ( isCancelled ) {
208+ return ;
209+ }
210+
211+ setFirstUploaded (
212+ < RelativeTime
213+ time = { versionData . datetime_created }
214+ suppressHydrationWarning
215+ />
216+ ) ;
217+ } catch ( error ) {
218+ if ( ! isCancelled ) {
219+ console . error ( "Failed to resolve version metadata" , error ) ;
220+ }
221+ }
222+ } ;
223+
224+ resolveVersionTimes ( ) ;
225+
226+ return ( ) => {
227+ isCancelled = true ;
228+ } ;
229+ } , [ isHydrated , version ] ) ;
173230 // END: For sidebar meta dates
174231
175232 const currentTab = location . pathname . split ( "/" ) [ 8 ] || "details" ;
176233
177234 const versionAndCommunityPromise = useMemo (
178235 ( ) => Promise . all ( [ version , community ] ) ,
179- [ ]
236+ [ version , community ]
180237 ) ;
181238
182- const versionAndTeamPromise = useMemo ( ( ) => Promise . all ( [ version , team ] ) , [ ] ) ;
239+ const versionAndTeamPromise = useMemo (
240+ ( ) => Promise . all ( [ version , team ] ) ,
241+ [ version , team ]
242+ ) ;
183243
184244 return (
185245 < >
186246 < Suspense >
187- < Await resolve = { versionAndCommunityPromise } >
247+ < Await
248+ resolve = { versionAndCommunityPromise }
249+ errorElement = { < NimbusAwaitErrorElement /> }
250+ >
188251 { ( resolvedValue ) => (
189252 < >
190253 < meta
@@ -233,7 +296,10 @@ export default function PackageVersion() {
233296 </ NewAlert >
234297 }
235298 >
236- < Await resolve = { version } >
299+ < Await
300+ resolve = { version }
301+ errorElement = { < NimbusAwaitErrorElement /> }
302+ >
237303 { ( resolvedValue ) => (
238304 < NewAlert csVariant = "warning" >
239305 You are viewing a potentially older version of this
@@ -257,7 +323,10 @@ export default function PackageVersion() {
257323 < SkeletonBox className = "package-listing__page-header-skeleton" />
258324 }
259325 >
260- < Await resolve = { version } >
326+ < Await
327+ resolve = { version }
328+ errorElement = { < NimbusAwaitErrorElement /> }
329+ >
261330 { ( resolvedValue ) => (
262331 < PageHeader
263332 headingLevel = "1"
@@ -323,15 +392,21 @@ export default function PackageVersion() {
323392 rootClasses = "package-listing__drawer"
324393 >
325394 < Suspense fallback = { < p > Loading...</ p > } >
326- < Await resolve = { version } >
395+ < Await
396+ resolve = { version }
397+ errorElement = { < NimbusAwaitErrorElement /> }
398+ >
327399 { ( resolvedValue ) => (
328400 < > { packageMeta ( firstUploaded , resolvedValue ) } </ >
329401 ) }
330402 </ Await >
331403 </ Suspense >
332404 </ Drawer >
333405 < Suspense fallback = { < p > Loading...</ p > } >
334- < Await resolve = { versionAndTeamPromise } >
406+ < Await
407+ resolve = { versionAndTeamPromise }
408+ errorElement = { < NimbusAwaitErrorElement /> }
409+ >
335410 { ( resolvedValue ) => (
336411 < Actions
337412 team = { resolvedValue [ 1 ] }
@@ -346,7 +421,10 @@ export default function PackageVersion() {
346421 < SkeletonBox className = "package-listing__nav-skeleton" />
347422 }
348423 >
349- < Await resolve = { version } >
424+ < Await
425+ resolve = { version }
426+ errorElement = { < NimbusAwaitErrorElement /> }
427+ >
350428 { ( resolvedValue ) => (
351429 < >
352430 < Tabs >
@@ -416,7 +494,10 @@ export default function PackageVersion() {
416494 < SkeletonBox className = "package-listing-sidebar__install-skeleton" />
417495 }
418496 >
419- < Await resolve = { version } >
497+ < Await
498+ resolve = { version }
499+ errorElement = { < NimbusAwaitErrorElement /> }
500+ >
420501 { ( resolvedValue ) => (
421502 < NewButton
422503 csVariant = "accent"
@@ -440,7 +521,10 @@ export default function PackageVersion() {
440521 < SkeletonBox className = "package-listing-sidebar__actions-skeleton" />
441522 }
442523 >
443- < Await resolve = { versionAndTeamPromise } >
524+ < Await
525+ resolve = { versionAndTeamPromise }
526+ errorElement = { < NimbusAwaitErrorElement /> }
527+ >
444528 { ( resolvedValue ) => (
445529 < Actions
446530 team = { resolvedValue [ 1 ] }
@@ -454,7 +538,10 @@ export default function PackageVersion() {
454538 < SkeletonBox className = "package-listing-sidebar__skeleton" />
455539 }
456540 >
457- < Await resolve = { version } >
541+ < Await
542+ resolve = { version }
543+ errorElement = { < NimbusAwaitErrorElement /> }
544+ >
458545 { ( resolvedValue ) => (
459546 < > { packageMeta ( firstUploaded , resolvedValue ) } </ >
460547 ) }
0 commit comments