diff --git a/scripts/handleErrors.ts b/scripts/handleErrors.ts index c946809e7..7d414236a 100644 --- a/scripts/handleErrors.ts +++ b/scripts/handleErrors.ts @@ -8,11 +8,31 @@ import { OsmConnection } from "../src/Logic/Osm/OsmConnection" import { ImmutableStore } from "../src/Logic/UIEventSource" import { Utils } from "../src/Utils" +type ErrorMessage = { + ip: string + index: number + date: string + message: { + stacktrace: string + message: string + layout: string + version: string + language: string + username: string + userid: number + pendingChanges: ChangeDescription[] + } +} + class HandleErrors extends Script { constructor() { super("Inspects the errors made on a given day. Argument: path to errors") } + parseLine() { + + } + async main(args: string[]): Promise { const osmConnection = new OsmConnection() const downloader = new OsmObjectDownloader(osmConnection.Backend(), undefined) @@ -29,26 +49,13 @@ class HandleErrors extends Script { osmConnection, }, false, err => console.error(err)) + const all: ErrorMessage[] = [] for (const line of lines) { if (!line?.trim()) { continue } try { - const parsed: { - ip: string - index: number - date: string - message: { - stacktrace: string - message: string - layout: string - version: string - language: string - username: string - userid: number - pendingChanges: ChangeDescription[] - } - } = JSON.parse(line) + const parsed: ErrorMessage = JSON.parse(line) const e = parsed.message if (e.layout === "grb") { console.log("Skipping GRB ") @@ -59,77 +66,87 @@ class HandleErrors extends Script { console.log( "\t https://osm.org/" + pendingChange.type + "/" + pendingChange.id, pendingChange.meta.changeType, - pendingChange.doDelete ? "DELETE" : "" + pendingChange.doDelete ? "DELETE" : "", ) } + all.push(parsed) - const neededIds = Changes.GetNeededIds(e.pendingChanges) - // We _do not_ pass in the Changes object itself - we want the data from OSM directly in order to apply the changes - const osmObjects: { id: string; osmObj: OsmObject | "deleted" }[] = - await Promise.all<{ - id: string - osmObj: OsmObject | "deleted" - }>( - neededIds.map(async (id) => ({ - id, - osmObj: await downloader.DownloadObjectAsync(id), - })) - ) - - const objects = osmObjects - .filter((obj) => obj.osmObj !== "deleted") - .map((obj) => obj.osmObj) - - const { toUpload, refused } = changesObj.fragmentChanges(e.pendingChanges, objects) - - const changes: { - newObjects: OsmObject[] - modifiedObjects: OsmObject[] - deletedObjects: OsmObject[] - } = new Changes({ - dryRun: new ImmutableStore(true), - osmConnection, - }).CreateChangesetObjects(toUpload, objects) - - const changeset = Changes.createChangesetFor("", changes) - const path = - "error_changeset_" + parsed.index + "_" + e.layout + "_" + e.username + ".osc" - if ( - changeset === - "" - ) { - console.log( - "Changes for " + - parsed.index + - ": empty changeset, not creating a file for it" - ) - } else if (createdChangesets.has(changeset)) { - console.log( - "Changeset " + - parsed.index + - " is identical to previously seen changeset, not writing to file" - ) - } else { - writeFileSync(path, changeset, "utf8") - createdChangesets.add(changeset) - } - const refusedContent = JSON.stringify(refused) - if (refusedFiles.has(refusedContent)) { - console.log( - "Refused changes for " + - parsed.index + - " is identical to previously seen changeset, not writing to file" - ) - } else { - writeFileSync(path + ".refused.json", refusedContent, "utf8") - refusedFiles.add(refusedContent) - } - console.log("Written", path, "with " + e.pendingChanges.length + " changes") } catch (e) { console.log("Parsing line failed:", e) } } + + for (const parsed of all) { + const e = parsed.message + const neededIds = Changes.GetNeededIds(e.pendingChanges) + // We _do not_ pass in the Changes object itself - we want the data from OSM directly in order to apply the changes + const osmObjects: { id: string; osmObj: OsmObject | "deleted" }[] = + await Promise.all<{ + id: string + osmObj: OsmObject | "deleted" + }>( + neededIds.map(async (id) => ({ + id, + osmObj: await downloader.DownloadObjectAsync(id), + })), + ) + + const objects = osmObjects + .filter((obj) => obj.osmObj !== "deleted") + .map((obj) => obj.osmObj) + + const { toUpload, refused } = changesObj.fragmentChanges(e.pendingChanges, objects) + + const changes: { + newObjects: OsmObject[] + modifiedObjects: OsmObject[] + deletedObjects: OsmObject[] + } = new Changes({ + dryRun: new ImmutableStore(true), + osmConnection, + }).CreateChangesetObjects(toUpload, objects) + + const changeset = Changes.createChangesetFor("", changes) + const path = + "error_changeset_" + parsed.index + "_" + e.layout + "_" + e.username + ".osc" + if ( + changeset === + "" + ) { + console.log( + "Changes for " + + parsed.index + + ": empty changeset, not creating a file for it", + ) + } else if (createdChangesets.has(changeset)) { + console.log( + "Changeset " + + parsed.index + + " is identical to previously seen changeset, not writing to file", + ) + } else { + writeFileSync(path, changeset, "utf8") + createdChangesets.add(changeset) + } + const refusedContent = JSON.stringify(refused) + if (refusedFiles.has(refusedContent)) { + console.log( + "Refused changes for " + + parsed.index + + " is identical to previously seen changeset, not writing to file", + ) + } else { + writeFileSync(path + ".refused.json", refusedContent, "utf8") + refusedFiles.add(refusedContent) + } + console.log("Written", path, "with " + e.pendingChanges.length + " changes") + + } } } -new HandleErrors().run() +new + +HandleErrors() + + .run()