Skip to content

Commit 0e0e5b7

Browse files
authored
Fix not to decode as JSON the empty response body (#1013)
## Changes This PR fixes the issue where JSON deserialization occurs even when the response body is empty. ## References - #998
1 parent 561d1b4 commit 0e0e5b7

File tree

12 files changed

+312
-104
lines changed

12 files changed

+312
-104
lines changed

generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/multipart.pebble

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
{% endfor %},
1515
form,
1616
);
17-
return {httpResponse: res, body: await res.json()};
17+
const text = await res.text();
18+
const parsedBody = text ? JSON.parse(text) : null;
19+
return { httpResponse: res, body: parsedBody };

generator/src/main/resources/line-bot-sdk-nodejs-generator/apiBody/normal.pebble

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,7 @@
4848
{% elseif op.hasQueryParams %}queryParams,{% endif %}
4949
{% if op.hasHeaderParams %}{headers: headerParams},{% endif %}
5050
);
51-
return {httpResponse: res, body: await res.json()};
51+
const text = await res.text();
52+
const parsedBody = text ? JSON.parse(text) : null;
53+
return { httpResponse: res, body: parsedBody };
5254
{% endif %}

lib/channel-access-token/api/channelAccessTokenClient.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ export class ChannelAccessTokenClient {
104104
"/oauth2/v2.1/tokens/kid",
105105
queryParams,
106106
);
107-
return { httpResponse: res, body: await res.json() };
107+
const text = await res.text();
108+
const parsedBody = text ? JSON.parse(text) : null;
109+
return { httpResponse: res, body: parsedBody };
108110
}
109111
/**
110112
* Issue short-lived channel access token
@@ -157,7 +159,9 @@ export class ChannelAccessTokenClient {
157159
"/v2/oauth/accessToken",
158160
formParams,
159161
);
160-
return { httpResponse: res, body: await res.json() };
162+
const text = await res.text();
163+
const parsedBody = text ? JSON.parse(text) : null;
164+
return { httpResponse: res, body: parsedBody };
161165
}
162166
/**
163167
* Issues a channel access token that allows you to specify a desired expiration date. This method lets you use JWT assertion for authentication.
@@ -210,7 +214,9 @@ export class ChannelAccessTokenClient {
210214
"/oauth2/v2.1/token",
211215
formParams,
212216
);
213-
return { httpResponse: res, body: await res.json() };
217+
const text = await res.text();
218+
const parsedBody = text ? JSON.parse(text) : null;
219+
return { httpResponse: res, body: parsedBody };
214220
}
215221
/**
216222
* Issues a new stateless channel access token, which doesn\'t have max active token limit unlike the other token types. The newly issued token is only valid for 15 minutes but can not be revoked until it naturally expires.
@@ -272,7 +278,9 @@ export class ChannelAccessTokenClient {
272278
});
273279

274280
const res = await this.httpClient.postForm("/oauth2/v3/token", formParams);
275-
return { httpResponse: res, body: await res.json() };
281+
const text = await res.text();
282+
const parsedBody = text ? JSON.parse(text) : null;
283+
return { httpResponse: res, body: parsedBody };
276284
}
277285
/**
278286
* Revoke short-lived or long-lived channel access token
@@ -306,7 +314,9 @@ export class ChannelAccessTokenClient {
306314
});
307315

308316
const res = await this.httpClient.postForm("/v2/oauth/revoke", formParams);
309-
return { httpResponse: res, body: await res.json() };
317+
const text = await res.text();
318+
const parsedBody = text ? JSON.parse(text) : null;
319+
return { httpResponse: res, body: parsedBody };
310320
}
311321
/**
312322
* Revoke channel access token v2.1
@@ -359,7 +369,9 @@ export class ChannelAccessTokenClient {
359369
"/oauth2/v2.1/revoke",
360370
formParams,
361371
);
362-
return { httpResponse: res, body: await res.json() };
372+
const text = await res.text();
373+
const parsedBody = text ? JSON.parse(text) : null;
374+
return { httpResponse: res, body: parsedBody };
363375
}
364376
/**
365377
* Verify the validity of short-lived and long-lived channel access tokens
@@ -393,7 +405,9 @@ export class ChannelAccessTokenClient {
393405
});
394406

395407
const res = await this.httpClient.postForm("/v2/oauth/verify", formParams);
396-
return { httpResponse: res, body: await res.json() };
408+
const text = await res.text();
409+
const parsedBody = text ? JSON.parse(text) : null;
410+
return { httpResponse: res, body: parsedBody };
397411
}
398412
/**
399413
* You can verify whether a Channel access token with a user-specified expiration (Channel Access Token v2.1) is valid.
@@ -427,6 +441,8 @@ export class ChannelAccessTokenClient {
427441
});
428442

429443
const res = await this.httpClient.get("/oauth2/v2.1/verify", queryParams);
430-
return { httpResponse: res, body: await res.json() };
444+
const text = await res.text();
445+
const parsedBody = text ? JSON.parse(text) : null;
446+
return { httpResponse: res, body: parsedBody };
431447
}
432448
}

lib/insight/api/insightClient.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ export class InsightClient {
8080
Types.ApiResponseType<GetFriendsDemographicsResponse>
8181
> {
8282
const res = await this.httpClient.get("/v2/bot/insight/demographic");
83-
return { httpResponse: res, body: await res.json() };
83+
const text = await res.text();
84+
const parsedBody = text ? JSON.parse(text) : null;
85+
return { httpResponse: res, body: parsedBody };
8486
}
8587
/**
8688
* Returns statistics about how users interact with narrowcast messages or broadcast messages sent from your LINE Official Account.
@@ -119,7 +121,9 @@ export class InsightClient {
119121
"/v2/bot/insight/message/event",
120122
queryParams,
121123
);
122-
return { httpResponse: res, body: await res.json() };
124+
const text = await res.text();
125+
const parsedBody = text ? JSON.parse(text) : null;
126+
return { httpResponse: res, body: parsedBody };
123127
}
124128
/**
125129
* Returns the number of users who have added the LINE Official Account on or before a specified date.
@@ -158,7 +162,9 @@ export class InsightClient {
158162
"/v2/bot/insight/followers",
159163
queryParams,
160164
);
161-
return { httpResponse: res, body: await res.json() };
165+
const text = await res.text();
166+
const parsedBody = text ? JSON.parse(text) : null;
167+
return { httpResponse: res, body: parsedBody };
162168
}
163169
/**
164170
* Returns the number of messages sent from LINE Official Account on a specified day.
@@ -197,7 +203,9 @@ export class InsightClient {
197203
"/v2/bot/insight/message/delivery",
198204
queryParams,
199205
);
200-
return { httpResponse: res, body: await res.json() };
206+
const text = await res.text();
207+
const parsedBody = text ? JSON.parse(text) : null;
208+
return { httpResponse: res, body: parsedBody };
201209
}
202210
/**
203211
* You can check the per-unit statistics of how users interact with push messages and multicast messages sent from your LINE Official Account.
@@ -250,6 +258,8 @@ export class InsightClient {
250258
"/v2/bot/insight/message/event/aggregation",
251259
queryParams,
252260
);
253-
return { httpResponse: res, body: await res.json() };
261+
const text = await res.text();
262+
const parsedBody = text ? JSON.parse(text) : null;
263+
return { httpResponse: res, body: parsedBody };
254264
}
255265
}

lib/liff/api/liffClient.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ export class LiffClient {
8787
const params = addLiffAppRequest;
8888

8989
const res = await this.httpClient.post("/liff/v1/apps", params);
90-
return { httpResponse: res, body: await res.json() };
90+
const text = await res.text();
91+
const parsedBody = text ? JSON.parse(text) : null;
92+
return { httpResponse: res, body: parsedBody };
9193
}
9294
/**
9395
* Deletes a LIFF app from a channel.
@@ -116,7 +118,9 @@ export class LiffClient {
116118
const res = await this.httpClient.delete(
117119
"/liff/v1/apps/{liffId}".replace("{liffId}", String(liffId)),
118120
);
119-
return { httpResponse: res, body: await res.json() };
121+
const text = await res.text();
122+
const parsedBody = text ? JSON.parse(text) : null;
123+
return { httpResponse: res, body: parsedBody };
120124
}
121125
/**
122126
* Gets information on all the LIFF apps added to the channel.
@@ -139,7 +143,9 @@ export class LiffClient {
139143
Types.ApiResponseType<GetAllLiffAppsResponse>
140144
> {
141145
const res = await this.httpClient.get("/liff/v1/apps");
142-
return { httpResponse: res, body: await res.json() };
146+
const text = await res.text();
147+
const parsedBody = text ? JSON.parse(text) : null;
148+
return { httpResponse: res, body: parsedBody };
143149
}
144150
/**
145151
* Update LIFF app settings
@@ -176,6 +182,8 @@ export class LiffClient {
176182
"/liff/v1/apps/{liffId}".replace("{liffId}", String(liffId)),
177183
params,
178184
);
179-
return { httpResponse: res, body: await res.json() };
185+
const text = await res.text();
186+
const parsedBody = text ? JSON.parse(text) : null;
187+
return { httpResponse: res, body: parsedBody };
180188
}
181189
}

lib/manage-audience/api/manageAudienceBlobClient.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ export class ManageAudienceBlobClient {
102102
"/v2/bot/audienceGroup/upload/byFile",
103103
form,
104104
);
105-
return { httpResponse: res, body: await res.json() };
105+
const text = await res.text();
106+
const parsedBody = text ? JSON.parse(text) : null;
107+
return { httpResponse: res, body: parsedBody };
106108
}
107109
/**
108110
* Create audience for uploading user IDs (by file).
@@ -155,6 +157,8 @@ export class ManageAudienceBlobClient {
155157
"/v2/bot/audienceGroup/upload/byFile",
156158
form,
157159
);
158-
return { httpResponse: res, body: await res.json() };
160+
const text = await res.text();
161+
const parsedBody = text ? JSON.parse(text) : null;
162+
return { httpResponse: res, body: parsedBody };
159163
}
160164
}

lib/manage-audience/api/manageAudienceClient.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ export class ManageAudienceClient {
9999
String(audienceGroupId),
100100
),
101101
);
102-
return { httpResponse: res, body: await res.json() };
102+
const text = await res.text();
103+
const parsedBody = text ? JSON.parse(text) : null;
104+
return { httpResponse: res, body: parsedBody };
103105
}
104106
/**
105107
* Add user IDs or Identifiers for Advertisers (IFAs) to an audience for uploading user IDs (by JSON)
@@ -133,7 +135,9 @@ export class ManageAudienceClient {
133135
"/v2/bot/audienceGroup/upload",
134136
params,
135137
);
136-
return { httpResponse: res, body: await res.json() };
138+
const text = await res.text();
139+
const parsedBody = text ? JSON.parse(text) : null;
140+
return { httpResponse: res, body: parsedBody };
137141
}
138142
/**
139143
* Create audience for uploading user IDs (by JSON)
@@ -165,7 +169,9 @@ export class ManageAudienceClient {
165169
"/v2/bot/audienceGroup/upload",
166170
params,
167171
);
168-
return { httpResponse: res, body: await res.json() };
172+
const text = await res.text();
173+
const parsedBody = text ? JSON.parse(text) : null;
174+
return { httpResponse: res, body: parsedBody };
169175
}
170176
/**
171177
* Create audience for click-based retargeting
@@ -199,7 +205,9 @@ export class ManageAudienceClient {
199205
"/v2/bot/audienceGroup/click",
200206
params,
201207
);
202-
return { httpResponse: res, body: await res.json() };
208+
const text = await res.text();
209+
const parsedBody = text ? JSON.parse(text) : null;
210+
return { httpResponse: res, body: parsedBody };
203211
}
204212
/**
205213
* Create audience for impression-based retargeting
@@ -230,7 +238,9 @@ export class ManageAudienceClient {
230238
const params = createImpBasedAudienceGroupRequest;
231239

232240
const res = await this.httpClient.post("/v2/bot/audienceGroup/imp", params);
233-
return { httpResponse: res, body: await res.json() };
241+
const text = await res.text();
242+
const parsedBody = text ? JSON.parse(text) : null;
243+
return { httpResponse: res, body: parsedBody };
234244
}
235245
/**
236246
* Delete audience
@@ -260,7 +270,9 @@ export class ManageAudienceClient {
260270
String(audienceGroupId),
261271
),
262272
);
263-
return { httpResponse: res, body: await res.json() };
273+
const text = await res.text();
274+
const parsedBody = text ? JSON.parse(text) : null;
275+
return { httpResponse: res, body: parsedBody };
264276
}
265277
/**
266278
* Gets audience data.
@@ -290,7 +302,9 @@ export class ManageAudienceClient {
290302
String(audienceGroupId),
291303
),
292304
);
293-
return { httpResponse: res, body: await res.json() };
305+
const text = await res.text();
306+
const parsedBody = text ? JSON.parse(text) : null;
307+
return { httpResponse: res, body: parsedBody };
294308
}
295309
/**
296310
* Get the authority level of the audience
@@ -313,7 +327,9 @@ export class ManageAudienceClient {
313327
const res = await this.httpClient.get(
314328
"/v2/bot/audienceGroup/authorityLevel",
315329
);
316-
return { httpResponse: res, body: await res.json() };
330+
const text = await res.text();
331+
const parsedBody = text ? JSON.parse(text) : null;
332+
return { httpResponse: res, body: parsedBody };
317333
}
318334
/**
319335
* Gets data for more than one audience.
@@ -384,7 +400,9 @@ export class ManageAudienceClient {
384400
"/v2/bot/audienceGroup/list",
385401
queryParams,
386402
);
387-
return { httpResponse: res, body: await res.json() };
403+
const text = await res.text();
404+
const parsedBody = text ? JSON.parse(text) : null;
405+
return { httpResponse: res, body: parsedBody };
388406
}
389407
/**
390408
* Change the authority level of the audience
@@ -418,7 +436,9 @@ export class ManageAudienceClient {
418436
"/v2/bot/audienceGroup/authorityLevel",
419437
params,
420438
);
421-
return { httpResponse: res, body: await res.json() };
439+
const text = await res.text();
440+
const parsedBody = text ? JSON.parse(text) : null;
441+
return { httpResponse: res, body: parsedBody };
422442
}
423443
/**
424444
* Renames an existing audience.
@@ -460,6 +480,8 @@ export class ManageAudienceClient {
460480
),
461481
params,
462482
);
463-
return { httpResponse: res, body: await res.json() };
483+
const text = await res.text();
484+
const parsedBody = text ? JSON.parse(text) : null;
485+
return { httpResponse: res, body: parsedBody };
464486
}
465487
}

lib/messaging-api/api/messagingApiBlobClient.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ export class MessagingApiBlobClient {
149149
String(messageId),
150150
),
151151
);
152-
return { httpResponse: res, body: await res.json() };
152+
const text = await res.text();
153+
const parsedBody = text ? JSON.parse(text) : null;
154+
return { httpResponse: res, body: parsedBody };
153155
}
154156
/**
155157
* Download rich menu image.
@@ -217,6 +219,8 @@ export class MessagingApiBlobClient {
217219
),
218220
params,
219221
);
220-
return { httpResponse: res, body: await res.json() };
222+
const text = await res.text();
223+
const parsedBody = text ? JSON.parse(text) : null;
224+
return { httpResponse: res, body: parsedBody };
221225
}
222226
}

0 commit comments

Comments
 (0)