diff --git a/src/backend/hafas/errors.nim b/src/backend/hafas/errors.nim new file mode 100644 index 0000000..0ab1270 --- /dev/null +++ b/src/backend/hafas/errors.nim @@ -0,0 +1,199 @@ +import asynchttpserver +import ../../types + +proc parseError*(errstr: string): hafasException = + case errstr: + of "H_UNKNOWN": + return hafasException( + code: SERVER_ERROR, + message: "unknown internal error", + statusCode: Http500, + ) + of "AUTH": + return hafasException( + code: ACCESS_DENIED, + message: "invalid or missing authentication data", + statusCode: Http401, + ) + of "R0001": + return hafasException( + code: INVALID_REQUEST, + message: "unknown method", + statusCode: Http400, + ) + of "R0002": + return hafasException( + code: INVALID_REQUEST, + message: "invalid or missing request parameters", + statusCode: Http400, + ) + of "R0007": + return hafasException( + code: SERVER_ERROR, + message: "internal communication error", + statusCode: Http500, + ) + of "R5000": + return hafasException( + code: ACCESS_DENIED, + message: "access denied", + statusCode: Http401, + ) + of "S1": + return hafasException( + code: SERVER_ERROR, + message: "journeys search: a connection to the backend server couldn\'t be established", + statusCode: Http503, + ) + of "LOCATION": + return hafasException( + code: INVALID_REQUEST, + message: "location/stop not found", + statusCode: Http400, + ) + of "H390": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: departure/arrival station replaced", + statusCode: Http400, + ) + of "H410": + return hafasException( + code: SERVER_ERROR, + message: "journeys search: incomplete response due to timetable change" + ) + of "H455": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: prolonged stop", + statusCode: Http400, + ) + of "H460": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: stop(s) passed multiple times", + statusCode: Http400, + ) + of "H500": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: too many trains, connection is not complete", + statusCode: Http400, + ) + of "H890": + return hafasException( + code: NOT_FOUND, + message: "journeys search unsuccessful", + statusCode: Http404, + ) + of "H891": + return hafasException( + code: NOT_FOUND, + message: "journeys search: no route found, try with an intermediate stations", + statusCode: Http404, + ) + of "H892": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: query too complex, try less intermediate stations", + statusCode: Http400, + ) + of "H895": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: departure & arrival are too near", + statusCode: Http400, + ) + of "H899": + return hafasException( + code: SERVER_ERROR, + message: "journeys search unsuccessful or incomplete due to timetable change" + ) + of "H900": + return hafasException( + code: SERVER_ERROR, + message: "journeys search unsuccessful or incomplete due to timetable change" + ) + of "H9220": + return hafasException( + code: NOT_FOUND, + message: "journeys search: no stations found close to the address", + statusCode: Http400, + ) + of "H9230": + return hafasException( + code: SERVER_ERROR, + message: "journeys search: an internal error occured", + statusCode: Http500, + ) + of "H9240": + return hafasException( + code: NOT_FOUND, + message: "journeys search unsuccessful", + statusCode: Http404, + ) + of "H9250": + return hafasException( + code: SERVER_ERROR, + message: "journeys search: leg query interrupted", + statusCode: Http500, + ) + of "H9260": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: unknown departure station", + statusCode: Http400, + ) + of "H9280": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: unknown intermediate station", + statusCode: Http400, + ) + of "H9300": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: unknown arrival station", + statusCode: Http400, + ) + of "H9320": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: the input is incorrect or incomplete", + statusCode: Http400, + ) + of "H9360": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: error in a data field", + statusCode: Http400, + ) + of "H9380": + return hafasException( + code: INVALID_REQUEST, + message: "journeys search: departure/arrival/intermediate station defined more than once", + statusCode: Http400, + ) + of "SQ001": + return hafasException( + code: SERVER_ERROR, + message: "no departures/arrivals data available", + statusCode: Http503, + ) + of "SQ005": + return hafasException( + code: NOT_FOUND, + message: "no trips found", + statusCode: Http404, + ) + of "TI001": + return hafasException( + code: SERVER_ERROR, + message: "no trip info available", + statusCode: Http503, + ) + return hafasException( + code: SERVER_ERROR, + message: "unknown HAFAS exception " & errstr, + statusCode: Http500, + ) diff --git a/src/backend/hafas/util.nim b/src/backend/hafas/util.nim index 11ab35b..44dba35 100644 --- a/src/backend/hafas/util.nim +++ b/src/backend/hafas/util.nim @@ -3,6 +3,7 @@ import asyncdispatch import md5 import json import strutils +import errors proc slug*(s: string): string = for c in s: @@ -47,4 +48,10 @@ proc request*(req: JsonNode): Future[JsonNode] {.async.} = #echo pretty body let req = await client.request(url, httpMethod = HttpPost, body = $body) let resp = await req.body - return parseJson(resp){"svcResL"}{0} + let data = parseJson(resp) + + let error = data{"svcResL"}{0}{"err"}.getStr() + if error != "OK": + raise parseError(error) + + return data{"svcResL"}{0} diff --git a/src/types.nim b/src/types.nim index f93dfa5..b0094e7 100644 --- a/src/types.nim +++ b/src/types.nim @@ -163,9 +163,6 @@ type polylines*: Option[bool] #default value: false support in hafas backend: ✅ tickets*: Option[bool] #default value: false support in hafas backend: ✅ - notFoundException* = object of Exception - errorException* = object of Exception - Polyline* = object `type`*: string features*: seq[Feature] @@ -192,6 +189,18 @@ type latitiude*: float longitude*: float + + notFoundException* = object of Exception + errorException* = object of Exception + + hafasExceptionKind* = enum + SERVER_ERROR, ACCESS_DENIED, INVALID_REQUEST, NOT_FOUND + + hafasException* = ref object of Exception + code*: hafasExceptionKind + message*: string + statusCode*: HttpCode + const MODES* = [ Train, # nationalExp Train, # national