@@ -41,27 +41,17 @@ inline fun <reified T, reified P : Partial<T>> HttpResponse.parseSearchResultIgn
4141 * information. Any error information contained in HTTP request or OCPI body gets converted into Exceptions.
4242 * @param offset
4343 */
44- inline fun <reified T > HttpResponse.parseSearchResult (offset : Int ): SearchResult <T > {
45- if (! status.success()) throw HttpException (status, status.name)
46- if (body.isNullOrBlank()) throw OcpiToolkitResponseParsingException (" missing obligatory body in response" )
47-
48- val list = runCatching { mapper.deserializeOcpiResponseList<T >(body) }
49- .onFailure { e ->
50- throw OcpiToolkitResponseParsingException (" Response cannot be parsed: $body " , e)
51- }
52- .getOrNull()
53- ?.also { it.maybeThrowOcpiException(status) }
54- ?.data ? : emptyList()
55-
56- return list.toSearchResult(
57- totalCount = getHeader(Header .X_TOTAL_COUNT )?.toInt()
58- ? : throw OcpiToolkitMissingRequiredResponseHeaderException (Header .X_TOTAL_COUNT ),
59- limit = getHeader(Header .X_LIMIT )?.toInt()
60- ? : throw OcpiToolkitMissingRequiredResponseHeaderException (Header .X_LIMIT ),
61- offset = offset,
62- nextPageUrl = getHeader(Header .LINK )?.split(" <" )?.elementAtOrNull(1 )?.split(" >" )?.first(),
63- )
64- }
44+ inline fun <reified T > HttpResponse.parseSearchResult (offset : Int ): SearchResult <T > =
45+ parseOcpiResponseBodyAndHandleErrors { mapper.deserializeOcpiResponseList<T >(body) }
46+ .orEmpty()
47+ .toSearchResult(
48+ totalCount = getHeader(Header .X_TOTAL_COUNT )?.toInt()
49+ ? : throw OcpiToolkitMissingRequiredResponseHeaderException (Header .X_TOTAL_COUNT ),
50+ limit = getHeader(Header .X_LIMIT )?.toInt()
51+ ? : throw OcpiToolkitMissingRequiredResponseHeaderException (Header .X_LIMIT ),
52+ offset = offset,
53+ nextPageUrl = getHeader(Header .LINK )?.split(" <" )?.elementAtOrNull(1 )?.split(" >" )?.first(),
54+ )
6555
6656/* *
6757 * Parse body of a request that should contain data, usually POST commands.
@@ -85,43 +75,52 @@ inline fun <reified T> HttpResponse.parseOptionalResult(): T? {
8575 return parseResultOrNull()
8676}
8777
88- inline fun <reified T > HttpResponse.parseResultListOrNull (): List <T >? {
89- if (! status.success()) throw HttpException (status, status.name)
90- if (body.isNullOrBlank()) throw OcpiToolkitResponseParsingException (" missing obligatory body in response" )
78+ inline fun <reified T > HttpResponse.parseResultListOrNull (): List <T >? =
79+ parseOcpiResponseBodyAndHandleErrors { mapper.deserializeOcpiResponseList<T >(body) }
9180
92- return runCatching { mapper.deserializeOcpiResponseList<T >(body) }
93- .onFailure { e ->
94- throw OcpiToolkitResponseParsingException (" Response cannot be parsed: $body " , e)
95- }
96- .getOrNull()
97- ?.also { it.maybeThrowOcpiException(status) }
98- ?.data
99- }
81+ inline fun <reified T > HttpResponse.parseResultOrNull (): T ? =
82+ parseOcpiResponseBodyAndHandleErrors { mapper.deserializeOcpiResponse<T >(it) }
10083
10184/* *
10285 * Parse body of a request that might contain data, like PUT/PATCH calls.
10386 * Any error information contained in HTTP request or OcpiResponseBody gets converted into Exceptions.
10487 */
105- inline fun <reified T > HttpResponse.parseResultOrNull (): T ? {
106- if (! status.success()) throw HttpException (status, status.name)
107- if (body.isNullOrBlank()) throw OcpiToolkitResponseParsingException (" missing obligatory body in response" )
88+ inline fun <reified T > HttpResponse.parseOcpiResponseBodyAndHandleErrors (
89+ deserializeFn : (String? ) -> OcpiResponseBody <T >,
90+ ): T ? {
91+ if (! status.success()) {
92+ // We know there was an error, so an exception must be thrown, we will try to throw an OcpiException if the
93+ // error is formatted as an OCPI error
94+ runCatching { deserializeFn(body) }
95+ .getOrElse {
96+ // If deserialization fails, it means that the response is probably not an OCPI error (if it is, it is
97+ // incorrectly formatted, so we read it as a regular HttpException)
98+ throw HttpException (status, status.name)
99+ }
100+ .throwOcpiException(status)
101+ }
108102
109- return runCatching { mapper.deserializeOcpiResponse<T >(body) }
110- .onFailure { e ->
103+ // We know the message is a success, so it must be formatted as an OCPI response, so we can safely throw an
104+ // exception if it is not the case
105+ return runCatching { deserializeFn(body) }
106+ .getOrElse { e ->
111107 throw OcpiToolkitResponseParsingException (" Response cannot be parsed: $body " , e)
112108 }
113- .getOrNull()
114- ?.also { it.maybeThrowOcpiException(status) }
115- ?.data
109+ .also { parsedOcpiResponse ->
110+ // who knows, maybe the partner responded with 200 or 201, but the OCPI payload is an error, in that case
111+ // throw the error
112+ if (! parsedOcpiResponse.statusCode.toOcpiStatus().isSuccess()) {
113+ parsedOcpiResponse.throwOcpiException(status)
114+ }
115+ }
116+ .data
116117}
117118
118- inline fun <reified T > OcpiResponseBody<T>.maybeThrowOcpiException (httpStatus : HttpStatus = HttpStatus .OK ) {
119- if (statusCode != OcpiStatus .SUCCESS .code) {
120- throw OcpiException (
121- httpStatus = httpStatus,
122- ocpiStatus = statusCode.toOcpiStatus(),
123- ocpiStatusCode = statusCode,
124- message = statusMessage ? : " " ,
125- )
126- }
119+ inline fun <reified T > OcpiResponseBody<T>.throwOcpiException (httpStatus : HttpStatus ) {
120+ throw OcpiException (
121+ httpStatus = httpStatus,
122+ ocpiStatus = statusCode.toOcpiStatus(),
123+ ocpiStatusCode = statusCode,
124+ message = statusMessage.orEmpty(),
125+ )
127126}
0 commit comments