Expose more of the results in Utils

This commit is contained in:
Pieter Vander Vennet 2022-12-15 20:24:53 +01:00
parent d1150be082
commit 2c785f6cb6

View file

@ -1,5 +1,5 @@
import * as colors from "./assets/colors.json" import * as colors from "./assets/colors.json"
import HTML = Mocha.reporters.HTML;
export class Utils { export class Utils {
/** /**
@ -139,7 +139,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
"false", "false",
] ]
private static injectedDownloads = {} private static injectedDownloads = {}
private static _download_cache = new Map<string, { promise: Promise<any>; timestamp: number }>() private static _download_cache = new Map<string, { promise: Promise<any | {error: string, url: string, statuscode?: number}>; timestamp: number }>()
/** /**
* Parses the arguments for special visualisations * Parses the arguments for special visualisations
@ -809,11 +809,13 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
* Download function which also indicates advanced options, such as redirects * Download function which also indicates advanced options, such as redirects
* @param url * @param url
* @param headers * @param headers
* @param onStatusCode Callback which is always triggered with the status code
*/ */
public static downloadAdvanced( public static downloadAdvanced(
url: string, url: string,
headers?: any headers?: any,
): Promise<{ content: string } | { redirect: string }> { onStatusCode?: (code:number) => void
): Promise<{ content: string } | { redirect: string } | { error: string,url: string, statuscode?: number}> {
if (this.externalDownloadFunction !== undefined) { if (this.externalDownloadFunction !== undefined) {
return this.externalDownloadFunction(url, headers) return this.externalDownloadFunction(url, headers)
} }
@ -821,14 +823,17 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest() const xhr = new XMLHttpRequest()
xhr.onload = () => { xhr.onload = () => {
if(onStatusCode ){
onStatusCode(xhr.status)
}
if (xhr.status == 200) { if (xhr.status == 200) {
resolve({ content: xhr.response }) resolve({ content: xhr.response })
} else if (xhr.status === 302) { } else if (xhr.status === 302) {
resolve({ redirect: xhr.getResponseHeader("location") }) resolve({ redirect: xhr.getResponseHeader("location") })
} else if (xhr.status === 509 || xhr.status === 429) { } else if (xhr.status === 509 || xhr.status === 429) {
reject("rate limited") resolve ({error: "rate limited", url, statuscode: xhr.status})
} else { } else {
reject("Could not download " + url + " due to " + xhr.statusText) resolve ({error: "other error: "+xhr.statusText, url, statuscode: xhr.status})
} }
} }
xhr.open("GET", url) xhr.open("GET", url)
@ -872,13 +877,25 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
maxCacheTimeMs: number, maxCacheTimeMs: number,
headers?: any headers?: any
): Promise<any> { ): Promise<any> {
const result = await Utils.downloadJsonAdvanced(url, headers)
if(result["content"]){
return result["content"]
}
throw result["error"]
}
public static async downloadJsonCachedAdvanced(
url: string,
maxCacheTimeMs: number,
headers?: any
): Promise<any | {error: string, url: string, statuscode?: number}> {
const cached = Utils._download_cache.get(url) const cached = Utils._download_cache.get(url)
if (cached !== undefined) { if (cached !== undefined) {
if (new Date().getTime() - cached.timestamp <= maxCacheTimeMs) { if (new Date().getTime() - cached.timestamp <= maxCacheTimeMs) {
return cached.promise return cached.promise
} }
} }
const promise = /*NO AWAIT as we work with the promise directly */ Utils.downloadJson( const promise = /*NO AWAIT as we work with the promise directly */ Utils.downloadJsonAdvanced(
url, url,
headers headers
) )
@ -887,26 +904,40 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
} }
public static async downloadJson(url: string, headers?: any): Promise<any> { public static async downloadJson(url: string, headers?: any): Promise<any> {
const result = await Utils.downloadJsonAdvanced(url, headers)
if(result["content"]){
return result["content"]
}
throw result["error"]
}
public static async downloadJsonAdvanced(url: string, headers?: any): Promise<{content: any} | {error: string, url: string, statuscode?: number}> {
const injected = Utils.injectedDownloads[url] const injected = Utils.injectedDownloads[url]
if (injected !== undefined) { if (injected !== undefined) {
console.log("Using injected resource for test for URL", url) console.log("Using injected resource for test for URL", url)
return new Promise((resolve, _) => resolve(injected)) return new Promise((resolve, _) => resolve({content: injected}))
} }
const data = await Utils.download( const result = await Utils.downloadAdvanced(
url, url,
Utils.Merge({ accept: "application/json" }, headers ?? {}) Utils.Merge({ accept: "application/json" }, headers ?? {})
) )
if(result["error"]){
return <{error: string, url: string, statuscode?: number}> result
}
const data = result["content"]
try { try {
if (typeof data === "string") { if (typeof data === "string") {
return JSON.parse(data) return JSON.parse(data)
} }
return data return {"content": data}
} catch (e) { } catch (e) {
console.error("Could not parse ", data, "due to", e, "\n", e.stack) console.error("Could not parse ", data, "due to", e, "\n", e.stack)
throw e return {error: "malformed", url}
} }
} }
/** /**
* Triggers a 'download file' popup which will download the contents * Triggers a 'download file' popup which will download the contents
*/ */