OpenAPITools / OpenAPITools/openapi-generator
[BUG][JS] Generated JS SDK result in the following error when called : end() was called twice. This is not supported in superagent
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
I use FastAPI to generate my routes, and the following command to produce the sdk:
docker run --network=host --rm \
-v $(pwd)/clients:/tmp \
openapitools/openapi-generator-cli:v4.0.0 generate \
-i localhost:8080/openapi.json \
-o /tmp/{language} \
-D modelDocs=false \
-D apiDocs=false \
-D apiTests=false \
-D modelTests=false \
-D npmVersion=3.5.2 \
-D supportsES6=true \
-g javascript
When producing the following code it result into this error message : .end() was called twice. This is not supported in superagent
Executed code:
useEffect(() => {
const api = new MyApi()
api.apiClient.basePath = 'http://localhost:8080'
api.produceSomethigGet().then(res => {
console.log(res)
})
}, [])
openapi-generator version
V4.0.0
OpenAPI declaration file content or url
https://gist.github.com/Thytu/517d892fadd685c921e7b0d780b1cd21
Generation Details
Steps to reproduce
Generate SDK:
docker run --network=host --rm \
-v $(pwd)/clients:/tmp \
openapitools/openapi-generator-cli:v4.0.0 generate \
-i localhost:8080/openapi.json \
-o /tmp/{language} \
-D modelDocs=false \
-D apiDocs=false \
-D apiTests=false \
-D modelTests=false \
-D npmVersion=3.5.2 \
-D supportsES6=true \
-g javascript
Call SDK:
useEffect(() => {
const api = new MyApi()
api.apiClient.basePath = 'http://localhost:8080'
api.produceSomethigGet().then(res => {
console.log(res)
})
}, [])
Related issues/PRs
Suggest a fix
I saw that if I change a bit the client code it does word:
Unchanged callApi function:
callApi(path, httpMethod, pathParams,
queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
returnType, apiBasePath, callback) {
var url = this.buildUrl(path, pathParams, apiBasePath);
var request = superagent(httpMethod, url);
if (this.plugins !== null) {
for (var index in this.plugins) {
if (this.plugins.hasOwnProperty(index)) {
request.use(this.plugins[index])
}
}
}
// apply authentications
this.applyAuthToRequest(request, authNames);
// set query parameters
if (httpMethod.toUpperCase() === 'GET' && this.cache === false) {
queryParams['_'] = new Date().getTime();
}
request.query(this.normalizeParams(queryParams));
// set header parameters
request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
// set requestAgent if it is set by user
if (this.requestAgent) {
request.agent(this.requestAgent);
}
// set request timeout
request.timeout(this.timeout);
var contentType = this.jsonPreferredMime(contentTypes);
if (contentType) {
// Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746)
if(contentType != 'multipart/form-data') {
request.type(contentType);
}
} else if (!request.header['Content-Type']) {
request.type('application/json');
}
if (contentType === 'application/x-www-form-urlencoded') {
request.send(querystring.stringify(this.normalizeParams(formParams)));
} else if (contentType == 'multipart/form-data') {
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
// file field
request.attach(key, _formParams[key]);
} else {
request.field(key, _formParams[key]);
}
}
}
} else if (bodyParam !== null && bodyParam !== undefined) {
request.send(bodyParam);
}
var accept = this.jsonPreferredMime(accepts);
if (accept) {
request.accept(accept);
}
if (returnType === 'Blob') {
request.responseType('blob');
} else if (returnType === 'String') {
request.responseType('string');
}
// Attach previously saved cookies, if enabled
if (this.enableCookies){
if (typeof window === 'undefined') {
this.agent._attachCookies(request);
}
else {
request.withCredentials();
}
}
request.end((error, response) => {
if (callback) {
var data = null;
if (!error) {
try {
data = this.deserialize(response, returnType);
if (this.enableCookies && typeof window === 'undefined'){
this.agent._saveCookies(response);
}
} catch (err) {
error = err;
}
}
callback(error, data, response);
}
});
return request;
}
Changed callApi function:
callApi(path, httpMethod, pathParams,
queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
returnType, apiBasePath, callback) {
var url = this.buildUrl(path, pathParams, apiBasePath);
var request = superagent(httpMethod, url);
if (this.plugins !== null) {
for (var index in this.plugins) {
if (this.plugins.hasOwnProperty(index)) {
request.use(this.plugins[index])
}
}
}
// apply authentications
this.applyAuthToRequest(request, authNames);
// set query parameters
if (httpMethod.toUpperCase() === 'GET' && this.cache === false) {
queryParams['_'] = new Date().getTime();
}
request.query(this.normalizeParams(queryParams));
// set header parameters
request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
// set requestAgent if it is set by user
if (this.requestAgent) {
request.agent(this.requestAgent);
}
// set request timeout
request.timeout(this.timeout);
var contentType = this.jsonPreferredMime(contentTypes);
if (contentType) {
// Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746)
if(contentType != 'multipart/form-data') {
request.type(contentType);
}
} else if (!request.header['Content-Type']) {
request.type('application/json');
}
if (contentType === 'application/x-www-form-urlencoded') {
request.send(querystring.stringify(this.normalizeParams(formParams)));
} else if (contentType == 'multipart/form-data') {
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
// file field
request.attach(key, _formParams[key]);
} else {
request.field(key, _formParams[key]);
}
}
}
} else if (bodyParam !== null && bodyParam !== undefined) {
request.send(bodyParam);
}
var accept = this.jsonPreferredMime(accepts);
if (accept) {
request.accept(accept);
}
if (returnType === 'Blob') {
request.responseType('blob');
} else if (returnType === 'String') {
request.responseType('string');
}
// Attach previously saved cookies, if enabled
if (this.enableCookies){
if (typeof window === 'undefined') {
this.agent._attachCookies(request);
}
else {
request.withCredentials();
}
}
// request.end((error, response) => {
// if (callback) {
// var data = null;
// if (!error) {
// try {
// data = this.deserialize(response, returnType);
// if (this.enableCookies && typeof window === 'undefined'){
// this.agent._saveCookies(response);
// }
// } catch (err) {
// error = err;
// }
// }
// callback(error, data, response);
// }
// });
return request;
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue with the provided FastAPI schema, the v4.0.0 Docker command, and the generated JavaScript client's callApi entry point. Compare the generated request behavior with the shown version that omits request.end(); done means the generated SDK no longer reports that superagent end() was called twice.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, javascript
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100