@@ -26,6 +26,53 @@ export default function Step1Publication() {
2626 else if ( publication . doi ) setQuery ( publication . doi ) ;
2727 } , [ publication ] ) ;
2828
29+ // Aquí fem un fetch amb alternatives, perquè els proxys públics a vegades peten (403, CORS, etc.)
30+ async function fetchWithFallback ( url , { timeoutMs = 12000 } = { } ) {
31+ const proxyOrder = [ "direct" , "allorigins" , "isomorphic" , "corsproxy" ] ;
32+ let lastErr = null ;
33+
34+ for ( const proxy of proxyOrder ) {
35+ const finalUrl = proxify ( url , proxy ) ;
36+ const ctrl = new AbortController ( ) ;
37+ const t = setTimeout ( ( ) => ctrl . abort ( ) , timeoutMs ) ;
38+
39+ try {
40+ const res = await fetch ( finalUrl , {
41+ method : "GET" ,
42+ signal : ctrl . signal ,
43+ headers : { Accept : "application/json" } ,
44+ } ) ;
45+
46+ clearTimeout ( t ) ;
47+
48+ if ( ! res . ok ) {
49+ lastErr = new Error ( `HTTP ${ res . status } (${ proxy } )` ) ;
50+ continue ;
51+ }
52+
53+ const json = await res . json ( ) ;
54+ return json ;
55+ } catch ( e ) {
56+ clearTimeout ( t ) ;
57+ lastErr = e ;
58+ continue ;
59+ }
60+ }
61+
62+ throw lastErr || new Error ( "No s'ha pogut fer la petició (tots els proxys han fallat)." ) ;
63+ }
64+
65+ function proxify ( url , proxyKind ) {
66+ const enc = encodeURIComponent ( url ) ;
67+
68+ if ( proxyKind === "direct" ) return url ;
69+ if ( proxyKind === "allorigins" ) return `https://api.allorigins.win/raw?url=${ enc } ` ;
70+ if ( proxyKind === "isomorphic" ) return `https://cors.isomorphic-git.org/${ url } ` ;
71+ if ( proxyKind === "corsproxy" ) return `${ PROXY } ${ enc } ` ;
72+
73+ return url ;
74+ }
75+
2976 // Cerca principal: pot ser PMID, DOI o títol
3077 async function handleSearch ( e ) {
3178 e . preventDefault ( ) ;
@@ -45,8 +92,7 @@ export default function Step1Publication() {
4592 // Cerca directa per PMID
4693 if ( isPMID ) {
4794 const url = `${ BASE } /esummary.fcgi?db=pubmed&id=${ q } &retmode=json` ;
48- const res = await fetch ( PROXY + encodeURIComponent ( url ) ) ;
49- const json = await res . json ( ) ;
95+ const json = await fetchWithFallback ( url ) ;
5096 const rec = json . result ?. [ q ] ;
5197
5298 if ( ! rec ) throw new Error ( "PMID no trobat" ) ;
@@ -67,14 +113,12 @@ export default function Step1Publication() {
67113 q
68114 ) } [doi]`;
69115
70- const r1 = await fetch ( PROXY + encodeURIComponent ( esearchUrl ) ) ;
71- const js1 = await r1 . json ( ) ;
116+ const js1 = await fetchWithFallback ( esearchUrl ) ;
72117 const pmid = js1 . esearchresult ?. idlist ?. [ 0 ] ;
73118
74119 if ( pmid ) {
75120 const esumUrl = `${ BASE } /esummary.fcgi?db=pubmed&id=${ pmid } &retmode=json` ;
76- const r2 = await fetch ( PROXY + encodeURIComponent ( esumUrl ) ) ;
77- const js2 = await r2 . json ( ) ;
121+ const js2 = await fetchWithFallback ( esumUrl ) ;
78122 const rec = js2 . result ?. [ pmid ] ;
79123
80124 if ( rec ) {
@@ -92,8 +136,7 @@ export default function Step1Publication() {
92136 // Fallback a CrossRef si PubMed no retorna res
93137 if ( ! data ) {
94138 const crUrl = `https://api.crossref.org/works/${ encodeURIComponent ( q ) } ` ;
95- const crRes = await fetch ( PROXY + encodeURIComponent ( crUrl ) ) ;
96- const crJson = await crRes . json ( ) ;
139+ const crJson = await fetchWithFallback ( crUrl ) ;
97140 const m = crJson . message ;
98141
99142 if ( ! m ) throw new Error ( "DOI no trobat a CrossRef" ) ;
@@ -117,15 +160,13 @@ export default function Step1Publication() {
117160 q
118161 ) } [title]`;
119162
120- const r1 = await fetch ( PROXY + encodeURIComponent ( esearchUrl ) ) ;
121- const js1 = await r1 . json ( ) ;
163+ const js1 = await fetchWithFallback ( esearchUrl ) ;
122164 const pmid = js1 . esearchresult ?. idlist ?. [ 0 ] ;
123165
124166 if ( ! pmid ) throw new Error ( "Cap article trobat amb aquest títol" ) ;
125167
126168 const esumUrl = `${ BASE } /esummary.fcgi?db=pubmed&id=${ pmid } &retmode=json` ;
127- const r2 = await fetch ( PROXY + encodeURIComponent ( esumUrl ) ) ;
128- const js2 = await r2 . json ( ) ;
169+ const js2 = await fetchWithFallback ( esumUrl ) ;
129170 const rec = js2 . result ?. [ pmid ] ;
130171
131172 data = {
@@ -143,9 +184,7 @@ export default function Step1Publication() {
143184 setArticle ( data ) ;
144185 } catch ( e ) {
145186 console . error ( e ) ;
146- setError (
147- "Error cercant l’article. Introdueix un PMID, un DOI o el títol."
148- ) ;
187+ setError ( "Error cercant l’article. Introdueix un PMID, un DOI o el títol." ) ;
149188 } finally {
150189 setLoading ( false ) ;
151190 }
@@ -199,7 +238,7 @@ export default function Step1Publication() {
199238 < p > < strong > Data:</ strong > { article . pubdate } </ p >
200239 < p > < strong > PMID:</ strong > { article . pmid || "—" } </ p >
201240 < p > < strong > DOI:</ strong > { article . doi || "—" } </ p >
202-
241+
203242 < div className = "pt-3" >
204243 < button className = "btn" onClick = { handleConfirm } >
205244 Confirmar i continuar →
0 commit comments