### 本家にある説明
https://join-lemmy.org/docs/en/client_development/http_api_extras.html#images
### WebUIで画像を添付した際の挙動
https://mastodon.juggler.jp/@tateisu/108832134849077396
### スクリプトから同じことをする
https://gist.github.com/tateisu/b71e42af44038c4262b1ebb62465930c
### pictrsの認証について
POST https://lemmy.juggler.jp/pictrs/image の認証は、LemmyにAPIでログインすると得られるauthを使って
リクエストヘッダに `Cookie: jwt=$auth` という感じでOKです。
IMAGE TEST!

IMAGE TEST!

IMAGE TEST!

async を使ってるのに例外をawaitで捕獲できずアプリが落ちる…? というのを体験した。
理由の説明はこの記事が詳しかった。
https://star-zero.medium.com/coroutines-async%E3%81%A8exception-9c0f079edb0e
- 親のキャンセルは子に伝えたい
- 子の例外はawait()で受け取りたい
…という用途では supervisorScope{} を使うのが良さそう。
スクラッチで試してみて概ね期待どおりだった。
```
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.supervisorScope
import java.lang.Thread.sleep
val scope = CoroutineScope(Job())
val job = scope.launch {
try {
supervisorScope {
val tasks = listOf(
async {
try {
delay(333L)
error("Test")
} catch (ex: Throwable) {
println("catch ex in async. ${ex.message}")
throw ex
}
}
)
try {
tasks.awaitAll()
} catch (ex: Throwable) {
println("catch ex in awaitAll. ${ex.message}")
throw ex
}
println("awaitAll complete.")
}
println("supervisorScope complete.")
} catch (ex: Throwable) {
println("catch ex in launch. ${ex.message}")
ex.printStackTrace()
}
println("launch complete.")
}
sleep(100L)
runBlocking {
// async内部からの例外発生を試したい場合
job.join()
// catch ex in async. Test
// catch ex in awaitAll. Test
// catch ex in launch. Test
// launch complete.
// または、上流からのキャンセル到達を試したい場合
// job.cancelAndJoin()
// catch ex in awaitAll. StandaloneCoroutine was cancelled
// catch ex in async. StandaloneCoroutine was cancelled
// catch ex in launch. StandaloneCoroutine was cancelled
// launch complete.
}
println("end.")
```