Original demand: Feature request: pasting images/files directly · Issue #10 · rxliuli/joplin-vscode-plugin · GitHub
Are there any examples available? I want to try to paste the image through vscode and upload it to joplin automatically. Are there any nodejs examples available?
static baseUrl(url: string, param?: object) {
const query = stringify(
{
...param,
token: config.token,
},
{
arrayFormat: 'comma',
},
)
return `http://localhost:${config.port}${url}?${query}`
}
async fileByResourceId(id: string) {
return (await axios.get(ApiUtil.baseUrl(`/resources/${id}/file`))).data
}
const res = await resourceApi.fileByResourceId(id)
console.log(typeof res)
const path = resolve(__dirname, '../resource/resourcesByFileId.png')
writeFileSync(path, res)
@laurent
Well, the creation still failed. . . @laurent
Error: Request failed with status code 500
const fd = new FormData()
const path = resolve(__dirname, '../resource/resourcesByFileId.png')
fd.append('props', JSON.stringify({ title: 'image' }))
fd.append('data', createReadStream(path))
const resp = await axios.post<ResourceGetRes>(
ApiUtil.baseUrl('/resources'),
fd,
{
headers: fd.getHeaders(),
},
)
console.log(resp.data)
console.log(res)
expect(res.id).toBe(id)
})
it.skip('test create', async () => {
const fd = new FormData()
const path = resolve(__dirname, '../resource/resourcesByFileId.png')
fd.append('props', JSON.stringify({ title: '图片标题' }))
fd.append('data', createReadStream(path))
await resourceApi.create(fd)
})
it('test create by fetch', async () => {
const fd = new FormData()
const path = resolve(__dirname, '../resource/resourcesByFileId.png')
fd.append('props', JSON.stringify({ title: 'image' }))
fd.append('data', createReadStream(path))
const resp = await axios.post<ResourceGetRes>(
ApiUtil.baseUrl('/resources'),
fd,
{
headers: fd.getHeaders(),
},
Does it give any error message beside code 500?
I assume the issue is that the request is not sent in multipart format but I can't be sure as I don't know this library.
The curl request would be:
curl -F 'data=@/path/to/file.jpg' -F 'props={"title":"my resource title"}' http://localhost:41184/resources
-F
means you upload the file as if it was from a form on a web page.
With curl it would be -F 'data=@/path/to/file.jpg'
(see the "@")
This is to make curl load the data from the given file. If you don't put "@" it assumes you want to post the string "/path/to/file.jpg" instead of the file content.
1 Like
Confirmed, there are some problems with axios. . . I use fetch (node-fetch) to upload normally
Ok that's good to know. I'd be curious to know how to replicate the 500 error you got though, as the app should have provided a proper error message.
Here is an example of axios unit test, you can simply run it here to reproduce
it('test create by fetch', async () => {
const fd = getFormData()
const resp = await fetch(ApiUtil.baseUrl('/resources'), {
method: 'post',
body: fd,
})
const json = await resp.json()
console.log('json: ', json)
})
it.skip('test create by axios', async () => {
const fd = getFormData()
const resp = await axios.post(ApiUtil.baseUrl('/resources'), fd, {
headers: fd.getHeaders(),
})
console.log('resp.data: ', resp.data)
})
})
it('test update', async () => {
const getRes = await resourceApi.get(id)
getRes.title = `new title ${Date.now()}`
clone repo && git checkout dev && yarn install
Start electron development client
Modify config.token(test/util/setupTestEnv.ts)
Remove the skip flag and run it
Get this error
You should be able to reproduce it with axios anywhere
Thanks for the information, I'll give it a try.
I was able to replicate the issue but there's no easy way to improve the error code. Technically it should be error 4xx since the request was invalid but since for certain cases it's hard to tell if it's an internal error or user error, an error 5xx is returned.
In general when testing the API, if you get a 500 error, the best is to look at the response body, which should contain detailed info about the error. For example:
$ curl --data '{"title":"bla"}' http://localhost:27583/tags?token=TOKEN
{"title":"bla","id":"35f4e2b755444e35bf2c9b34fff88936","updated_time":1602237094307,"created_time":1602237094307,"user_updated_time":1602237094307,"user_created_time":1602237094307,"type_":5}
$ curl --data '{"title":"bla"}' http://localhost:27583/tags?token=TOKEN
{"error":"Internal Server Error: The tag "bla" already exists. Please choose a different name.: \n\nError: The tag "bla" already exists. Please choose a different name.\n at Function.save (/home/laurent/source/joplin/ElectronClient/lib/models/Tag.js:184:55)"}
Now, I filed a bug for axios. . .
opened 10:24AM - 09 Oct 20 UTC
Describe the issue
The code below uses node-fetch and axios to upload pictures, I don’t understand why axios fails
Example Code
Code snippet to...
type:question
Part of the issue, and I don't know if it's a problem with axios or Jest, is that when there's an error it just displays "failed with status code 500", but Joplin actually sends back detailed info about the error, which is not being displayed here. If it was it would be easy to tell if it's an error in the test, or Axios, or Joplin.
But fetch succeeded, so. . .