kagamihogeの日記

kagamihogeの日記です。

WebFluxでBindingResultをWebExchangeBindExceptionに書き換え

WebFluxではWebMVCのようにメソッド引数でBindingResultでvalidation結果を取得できないので、その書き換え方について。

WebMVCではcontrollerでvalidation結果を取得するにはメソッドの引数にBindingResultを追加する。例えば以下のようなコードになる。以下では、もしvalidationエラーが発生したら、一旦BindExceptionに変換してcontroller-adviceでエラーハンドリングを行う、というのを想定している。これを書き換えていく。

import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpringMvcConrtoller {

  @PostMapping("/item1")
  public Item item(@Validated Item item, BindingResult result) throws BindException {
    if (result.hasErrors()) {
      throw new BindException(result);
    }
    return new Item();
  }
}

ソースコード

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.0'
    id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
    useJUnitPlatform()
}

書き換え例

引数にBindingResultがあると実行時エラーになるので削除する。また、引数オブジェクトをMonoとかでラップし、そのMonoを使用して処理を記述する。以下はmapで単に空オブジェクトを返すだけだが、こういう感じにロジックを記述する。もしvalidationが失敗するとWebExchangeBindExceptionになるのでこれをonErrorMapなどエラーハンドラで処理する。ここでは最初のSpringMVCの例に合わせて単にBindExceptionに詰め替えしている。*1

import org.springframework.validation.BindException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.support.WebExchangeBindException;
import reactor.core.publisher.Mono;

@RestController
public class WebFluxController {
  @PostMapping("item001")
  public Mono<Item> item(@Validated Mono<Item> request) {
    return request
        .map(item -> new Item())
        .onErrorMap(WebExchangeBindException.class, e -> {
          return new BindException(e.getBindingResult());
        });
  }
}

エラーハンドリングはAbstractErrorWebExceptionHandlerの継承クラスを用意し、例外ごとの処理を記述する。こういうのはJDK 21のswitchの使用例になるだろうか。

import org.springframework.boot.autoconfigure.web.WebProperties.Resources;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Component
public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

  public CustomErrorWebExceptionHandler(ErrorAttributes errorAttributes,
      ApplicationContext applicationContext,
      ServerCodecConfigurer serverCodecConfigurer) {
    super(errorAttributes, new Resources(), applicationContext);
    super.setMessageWriters(serverCodecConfigurer.getWriters());
    super.setMessageReaders(serverCodecConfigurer.getReaders());
  }

  @Override
  protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
    return RouterFunctions.route(RequestPredicates.all(), r -> {
      ErrorAttributeOptions eao = ErrorAttributeOptions.defaults();

      Throwable error = errorAttributes.getError(r);
      return switch (error) {
        case BindException e -> ServerResponse.status(400).bodyValue("validation error");
        default -> ServerResponse.status(500).bodyValue("default");
      }
    });
  }
}

試行錯誤

以下はあーだこーだと調べたり試したりした際の作業メモ。

まずは単に戻り値型をMonoに変えるだけで実行してみる。

import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class WebFluxController {

  @PostMapping("item001")
  public Mono<Item> item(@RequestBody @Validated Item item, BindingResult result) throws BindException {
    if (result.hasErrors()) {
      throw new BindException(result);
    }
    return Mono.just(new Item());
  }

以下のエラーになる。

java.lang.IllegalStateException: An Errors/BindingResult argument is expected immediately after the @ModelAttribute argument to which it applies. For @RequestBody and @RequestPart arguments, please declare them with a reactive type wrapper and use its onError operators to handle WebExchangeBindException: public reactor.core.publisher.Mono org.example.app.WebFluxController.item(org.example.app.Item,org.springframework.validation.BindingResult) throws org.springframework.validation.BindException
    at org.springframework.util.Assert.state(Assert.java:101) ~[spring-core-6.2.0.jar:6.2.0]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ? HTTP POST "/item001" [ExceptionHandlingWebHandler]
Original Stack Trace:

エラーメッセージに従い、引数オブジェクトをMonoでラップする。

  @PostMapping("item001")
  public Mono<Item> item(@RequestBody @Validated Mono<Item> item, BindingResult result) throws BindException {
   ...

以下のエラーになる。

java.lang.IllegalStateException: An @ModelAttribute and an Errors/BindingResult argument cannot both be declared with an async type wrapper. Either declare the @ModelAttribute without an async wrapper type or handle a WebExchangeBindException error signal through the async type.
    at org.springframework.util.Assert.state(Assert.java:79) ~[spring-core-6.2.0.jar:6.2.0]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ? HTTP POST "/item001" [ExceptionHandlingWebHandler]
Original Stack Trace:

エラーメッセージに従い、引数からBindingResultを削除してWebExchangeBindExceptionのエラーハンドリングに切り替える。これは上述の通り。

もし以下のようにWebExchangeBindExceptionをそのまま返すだけにしたらどうなるか? AbstractErrorWebExceptionHandlerに行かない。

  @PostMapping("item001")
  public Mono<Item> item(@Validated Mono<Item> request) {
    return request
        .map(item -> new Item())
        .onErrorMap(WebExchangeBindException.class, e -> {
          return e;
        });
  }

参考文献

*1:WebFluxほぼ経験ゼロなのでreactive由来の用語の使い方が変だと思うがスルーして欲しい

spring-bootでControllerAdviceのExceptionHandlerが呼ばれるまでの流れ

spring-bootでは@ControllerAdvice / @RestControllerAdviceによりcontollerの例外処理を一か所にまとめられる。このエントリでは例外が発生してadviceのメソッドが実際に呼び出されるまでのコードを追う。

ソースコードのバージョンはこれを書いてる 2024/11 月頃のgithubを参照しているが、余程大規模な変更がされない限りそこまで大きくは変わらないとは思う。

例外発生時の流れ

DispatcherServletから例外リゾルバに解決を依頼

まずはDispatcherServletから始まる。これの詳細は省略するが、簡単に言えば各controllerへのdispatchを担当している。以下のha.handleがそのdispatchに相当する。そのdispatch、つまりcontrollerの各メソッド呼出、が例外をthrowしたらcatchする。その例外はprocessDispatchResultに渡す。

public class DispatcherServlet extends FrameworkServlet {
..
  protected void doDispatch(...) .. {
    try {
      ...
      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
      ...
    } catch (Exception ex) {
      dispatchException = ex;
    ..
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

processDispatchResultはconroller呼出結果に対する処理。もし例外が発生していたらprocessHandlerExceptionを呼ぶ。

private void processDispatchResult(...) throws Exception {
  ...
  if (exception != null) {
    ...
  else {...
     mv = processHandlerException(request, response, handler, exception);

processHandlerExceptionは例外に対する処理。自身に登録されている例外リゾルバーに解決を依頼する。その戻り値型はModelAndViewなので、例外リゾルバーの実装に応じてエラーページ表示したりなんだりが最終的に行われる。

protected ModelAndView processHandlerException(...) throws Exception {
  ModelAndView exMv = null;
  for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
    exMv = resolver.resolveException(request, response, handler, ex);

ExceptionHandlerExceptionResolverが例外を解決

例外の解決にはspring-bootのデフォルトではExceptionHandlerExceptionResolverが使用される*1。ここではmapで例外型に対するメソッドを保持しており、例外の解決をそのメソッドに依頼する、という処理になる。

このクラスはexceptionHandlerAdviceCacheというプロパティがあり、キーがcontroller-adviceで値はそれに対応する例外処理クラスのmapを保持している。

public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver
  implements ApplicationContextAware, InitializingBean {
  
  private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = new LinkedHashMap<>();

キーのControllerAdviceBean は名前そのままのcontroller-adviceを表現するためのクラスなので詳細は省略する。値のExceptionHandlerMethodResolverは以下のように、キーが例外型で値がそれに対応するMethodのmapを保持している。つまり、controller-advice -> 例外型 -> Method(@ExceptionHandlerのメソッド)、というマッピングをここで保持している。

public class ExceptionHandlerMethodResolver {
  private final Map<ExceptionMapping, ExceptionHandlerMappingInfo> mappedMethods = new HashMap<>(16);

  private record ExceptionMapping(Class<? extends Throwable> exceptionType, MediaType mediaType) {
public class ExceptionHandlerMappingInfo {
  ..
  private final Method handlerMethod;

以上がcontrollerが例外をthrowするとcontroller-adviceの@ExceptionHandlerが呼ばれる大まかな流れとなる。

例外リゾルバー登録の流れ

ApplicationContext経由でExceptionHandlerExceptionResolverを登録

次に、DispatcherServletExceptionHandlerExceptionResolverが登録されるまでの流れを見る。WebApplicationContextリフレッシュでinitHandlerExceptionResolversでリゾルバを初期化している。この初期化ではHandlerExceptionResolverのmanaged-beanをすべて取得する。その一つが先に見たExceptionHandlerExceptionResolverである。

public class DispatcherServlet extends FrameworkServlet {
  ..
  @Override
  protected void onRefresh(ApplicationContext context) {
    initStrategies(context);
    ..

  protected void initStrategies(ApplicationContext context) {
    ..
    initHandlerExceptionResolvers(context);
    ...

  private void initHandlerExceptionResolvers(ApplicationContext context) {
    ..
    Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);

spring-bootが生成したExceptionHandlerExceptionResolverのmanaged-beanがApplicationContext(WebApplicationContext)を介してDispatcherServletに登録されているのが分かる。

auto-configによるデフォルトのmanaged-bean生成

ExceptionHandlerExceptionResolverのmanaged-beanはどこで生成されるのか。簡単に言えばspring-bootのauto-configの仕組みで生成される。auto-configの詳細は省略するが、今回のエントリで関係する部分だけを抜粋する。

デフォルトでは、まずauto-configでWebMvcAutoConfigurationが有効となり、そのクラス内のstaticなconfig WebMvcAutoConfigurationAdapterが有効となり、その@ImportEnableWebMvcConfigurationが有効となる。

..
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, .. })
public class WebMvcAutoConfiguration {

  ..
  @Import(EnableWebMvcConfiguration.class)
  public static class WebMvcAutoConfigurationAdapter ..

  ..
  @Configuration(proxyBeanMethods = false)
  public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration ..

EnableWebMvcConfigurationの親クラス階層にWebMvcConfigurationSupportがある。ここでHandlerExceptionResolverのmanaged-beanを生成する。ここの詳細は省略するが、下記のように、デフォルトではExceptionHandlerExceptionResolverのmanaged-beanが生成される。

public class WebMvcConfigurationSupport ..
  @Bean
  public HandlerExceptionResolver handlerExceptionResolver(
    ..
      addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);

  protected final void addDefaultHandlerExceptionResolvers(..) {
    ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();
    ..

  protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() {
    return new ExceptionHandlerExceptionResolver();

auto-configがデフォルトのExceptionHandlerExceptionResolverのmanaged-beanを生成しているのが分かる。

ControllerAdviceBeanマップの生成

ExceptionHandlerExceptionResolverでキーがcontroller-adviceで値はそれに対応する例外処理クラスのmapを保持しているのは先に述べた。では、そのmapはどのように生成しているのか。以下のように、このmanaged-bean生成時にControllerAdviceBean.findAnnotatedBeansでadviceのmanaged-beanリストを取得している。

public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver .. {
  ..
  private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
            new LinkedHashMap<>();

  @Override
  public void afterPropertiesSet() {
    initExceptionHandlerAdviceCache();
  ..

  private void initExceptionHandlerAdviceCache() {
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
  for (ControllerAdviceBean adviceBean : adviceBeans) {
    Class<?> beanType = adviceBean.getBeanType();
    ..
    ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
    if (resolver.hasExceptionMappings()) {
      this.exceptionHandlerAdviceCache.put(adviceBean, resolver);

このメソッドは単に@ControllerAdviceを持つmanaged-beanのリストを取得する。

public class ControllerAdviceBean implements Ordered {
  ..
  public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) {
    ..
    for (String name : ...) {
      ControllerAdvice controllerAdvice = beanFactory.findAnnotationOnBean(name, ControllerAdvice.class);
      ..
        adviceBeans.add(new ControllerAdviceBean(name, beanFactory, controllerAdvice));

@ExceptionHandlerの付与されたメソッドの取得は下記あたりで行っている。

public class ExceptionHandlerMethodResolver {
  private static final MethodFilter EXCEPTION_HANDLER_METHODS = method -> AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);

  ..
  public ExceptionHandlerMethodResolver(Class<?> handlerType) {
    for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
      ExceptionHandlerMappingInfo mappingInfo = detectExceptionMappings(method);
      ..

  private ExceptionHandlerMappingInfo detectExceptionMappings(Method method) {
    ExceptionHandler exceptionHandler = readExceptionHandlerAnnotation(method);
    ..

  private ExceptionHandler readExceptionHandlerAnnotation(Method method) {
    ExceptionHandler ann = AnnotatedElementUtils.findMergedAnnotation(method, ExceptionHandler.class);

その他

ControllerAdviceとRestControllerAdviceは内部的には同一

アノテーションは内部的にはどちらもControllerAdviceと同一扱いされる、と考えてよい。以下の定義に見るように、RestControllerAdviceにはControllerAdvice(とResponseBody)が付与されている。このためcontext.findAnnotationOnBean("adviceBeanName", ControllerAdvice.class);とかやるとどちらかのアノテーションがあればControllerAdviceが付与されたbeanとして取得できる。また@AliasForRestControllerAdviceのパラメータはすべてControllerAdviceの同名のものに引き渡される。

@Component
public @interface ControllerAdvice {
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
  @AliasFor(annotation = ControllerAdvice.class)
  String name() default "";

関連ソースコード

https://github.com/spring-projects/spring-framework/blob/main/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java

https://github.com/spring-projects/spring-framework/blob/main/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMappingInfo.java

https://github.com/spring-projects/spring-framework/blob/main/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExceptionResolver.java

https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java

https://github.com/spring-projects/spring-framework/blob/main/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/bind/annotation/RestControllerAdvice.java

*1:実際には他のリゾルバも登録される。なので、正確には、このケースではExceptionHandlerExceptionResolverが使用される、と書いた方が良いかもしれない。ただ今回のエントリの主旨では無いので省略。

全焼日記

2023年のある日、私が居住していた賃貸アパートが全焼した。

はじめに 必ず日常は取り戻せる

将来、住宅火災に見舞われた方がこの日記にたどり着くかもしれない。私と同じように住宅火災で家屋を失った方向けの文章からまず始める。一言で言えば、必ず日常は取り戻せる。心配は要らない。絶望的な気分に陥るのは当然だがさほど心配は要らない。

大規模な災害、例えば地震津波・洪水、などと住宅火災は異なり付近の建造物は無事である。余程の大火事なら別だが一般的な住宅火災なら延焼してもせいぜい数件隣までである。少し離れたスーパーやコンビニで物資は購入できるし、役所で手続きも出来るし、ビジネスホテルやウィークリーマンションに宿泊もできる。近所に知人が居ればそれを頼れる。飲料水も寝る場所も無い、という極限状態にいきなり陥る可能性は低い。つまり、今日・明日の生命の心配は不要である。

次に、当座はしのげるとして、生活の復旧に必要な期間はどの程度だろうか? 私は3週間および3か月が目安だと考えている。

3週間は職場復帰タイミングの目安である。別の方のレポートを見ていてもおおむねこのタイミングになるようだ。心身ともに頑強なら2週間以内も可能だろうが、何か事情が無い限りは無理は避けた方が無難だろう。最初の1週間は怒涛の勢いで過ぎてゆき、2-3週間目は様々な手続きや次の住居の準備にかかりきりになる。心身ともに疲労が取れない中で慣れない手続きをあれこれ片づけなければならない。ミスやロスはどうしても多くなる。休息は必須である。これらを考慮すると、職場復帰に3週間は必要だろう。

3か月は次の生活がおおむね落ち着くであろう目安である。私は独身なので1か月目はマンスリーマンション、その間に適当な賃貸物件を探して2か月目から引っ越し、が大まかなスケジュールだった。家財道具をゼロから買い直し、引っ越し先の近所のスーパーやドラッグストアへ日々の買い出しなど一通りの生活サイクルが問題無く回る実感が沸くのにおおむね2か月。合計3か月。ただ、これは身軽で体力もある独身男性の場合である。

戸建てで家族ありの場合は更に時間が必要だろう。別の方のレポートを見ると、3か月は仮住まいの賃貸や知人宅での生活がなんとか落ち着くタイミングになるようだ。戸建てを再建するか、それとも別の賃貸を探すか。そうした次のステップを考え始めるタイミングになるだろう。

ともあれ、まずは3週間と3か月を乗り越える事だけに専念すべき。必ず日常は取り戻せる。

全焼日記

1日目

2023年のある日の深夜未明、就寝中の私は奇妙な焼け焦げ臭に目を覚ました。焼肉で肉野菜きのこなど同時に焦がすと様々なものが混ざった変な臭い匂いになるが、あれを何十倍も強力にした異臭だった。寝ぼけ眼のままほとんど無意識で財布とスマホだけ掴んで外へ異常の確認へ向かう。財布とスマホを掴んだ事が後々の生活再建に多大な意味を持つ事になる。

玄関を抜けるとそこは黒煙だった。

いつもの廊下どころか足元どころか手元すら見えない。防災訓練の煙体験の記憶が瞬時に蘇る。反射的にひじの裏側で口元を覆うと、姿勢を低くし、階段まで一気に走り抜ける。幸いにも、火災は一戸分で左右への延焼はまだだった。ほんの数メートル走れば黒煙を抜けれたのは本当に幸運だった。

当時のアパートは2階建てで私は2階に住んでいた。階段を駆け下りながら火元を確認すると私の居室の真下。素人目にも消火器ではもうどうにもならない規模の火炎が見える。あと数分気付くのが遅かったら、俺はどうなっていただろうか? 緊急事態なのは明らかだったが、寝起きで頭が回らないし、火事とか意味が分からなさ過ぎるし、混乱したまま火元に近寄っていく。すると火元の住人であろう老人が途方に暮れて座り込んでるのが見えた。開け放たれた玄関ドアから1階居室の天井に火災が届いているのが見える。あぁ、これ、火事なのか。そうなのか。

誰も! 消防車を呼んでいないのである!

俺もインターネットにかぶれた住人なので例のフレーズが頭をよぎる。だが手前の家が燃えてるのだ。アホ言ってる場合ではない。だが、だが本当に住宅火災は混乱する。混乱してるのに、意味不明な思考が勝手に浮かんで、また混乱する。

ようやく119を決断する。スマホに緊急通報機能があるのは知っていたが、とてもじゃないが冷静に使えはしなかった。電話をタップ、手が震える、1111..、手が震えて119が押せない。何度も繰り返してやっと119が成功する。一瞬で繋がる。

「火事ですか、救急ですか」

あぁードキュメンタリー番組で見るやり取りって本当なんだな……どこか冷静に諦めた自分が居たのを今も覚えている。

「火事です」 「住所と氏名をお願いします」 「xxでyyです」 「すぐに到着します。安全な場所に避難してください」

避難しろといっても他の住人を放置するわけにもいかない。ここで異常に気付いた他の住人が何人か起きだしてくる。協力してドアをブチ破る勢いで叩き起こす。1階はベランダに回り込んで半ば引きずり出すようにして裸足で避難させてもいたようだ。どうにかこうにか全員着の身着のまま避難は出来た。

そうこうするうちサイレンが聴こえてくる。住民避難に必死だったのもあるが本当に一瞬で到着した。道路に飛び出していって消防車を誘導すると消火活動が始まる。これで一段落つく……どころか長い長い夜の始まりだった。

「第一通報者はどこですか!」

次々に緊急車両が到着すると簡易指揮所が置かれて俺が呼び出される。119から緊急車両到着までの状況をなるべく細かく話すよう指示が出る。「深夜未明の就寝時、異臭に気付いて目が覚めて……」 それからアパートの間取り、各居室の居住実態、現在の避難状況、安否確認……俺も被害者だけど何で緊急対応の協力者になってるんだ?

「警察です、第一通報者の方は詳しい状況を……」
「役所です、第一通報者の方は詳しい状況を……」
「〇×(覚えてない)です、第一通報者の方は詳しい状況を……」

何度も何度も何度も「深夜未明の就寝時、異臭に気付いて目が覚めて……」をオウムが如く繰り返す。乞われるがままに情報を垂れ流すし、やれと言われた事はやる。アドレナリンだか何だかで疑問も無いし疲れも無い。情報システムの運用でも緊急対応時はその担当者・専門家の言われるがまま作業した方が良い。警察や消防の方を怒鳴りつけたり泣きついても何も変わらないのだ。頭の片隅に居る冷静な自分がそう言っている。

そうこうするうちに本格的な消火活動が開始され、私も解放されてただ立ち尽くすのみとなった。屋根から炎が噴き出して建物全体から大量の黒煙が噴き出している。全焼は誰の目にも明らかだった。道を埋め尽くす大量の緊急車両と慌ただしく現場を駆け回る沢山の消防士たち。ちんけなアパートによくもまぁ懸命なことか、頭が下がるやら悲しくなるばかりやら。「放火なら訴えてやる」怒りでもしないとやってられないだろう者も居れば、冷たい地面に力なく座り込む者もいる。私の頭にはとりとめない事ばかりが浮かんでくる。会社とか家族とか連絡しなきゃなぁ、ツイッターもなんてつぶやくかなぁ。スマホ無事だしソシャゲのデイリー報酬くらいはもらうかぁ。紙幣は燃えただろうなぁ、本とかグッズも全滅かなぁ……

どのくらい立ち尽くしていただろうか、近所に住む大家さんが一室を我々入居者の避難先にする準備が出来た、と伝えに来た。もし延焼が大規模化すれば大家さん宅も危険だったので避難していたようだが、消火活動によりその危険性が無くなってから準備をして頂けたようだ。大変にありがたい申し出なので素直に頼ることに。

なお、役所も一時避難場所の提供はある。ただし、会議室を開けるだけで毛布だとかは一切無い。せいぜい椅子を並べて簡易ベッドにするくらいだろう。また、そこまでの移動手段は自分で用意しなければならない。大人の足でも徒歩約20分、疲れ切った状態では健康な成人男性でも中々にきつい。深夜にタクシーがつかまるかどうか不透明だし、大半の入居者は決済手段を持ち出せていない。そのため、大家さんの申し出は大変にありがたかった。

毛布が敷き詰められた部屋に横たわる。会話は無く重苦しい沈黙が支配する。入居者同士の交流は挨拶くらいで普段の交流はゼロに等しい。それでなくとも、突然の出来事に呆然とするしかない。俺は目がさえてしまって眠れないが、少しでも体力を回復・温存したくてとにかく横たわって目をつむる。翌朝から生活再建に動かなければならない。何をすれば良いかは検討もつかないが、体力だけは必要になるだろう。その一心で身体を休める。

火災現場では消防士から今後の手続き関連の手引きを渡される。https://www.city.kawasaki.jp/840/page/0000151906.html のリンクに PDF でその手引書https://www.city.kawasaki.jp/840/cmsfiles/contents/0000151/151906/2023.3.pdf がある。

基本的には、住宅火災後の行政関連の手続きはこの手引きに従い一つ一つクリアする事になるが、一番最初は保険会社への一報になる。火災保険の申請には消防署が発行する、り災証明書が必要だが、これは消防署が諸所の手続きを終えてから発行可能になるので、入手には時間がかかる。それまでに進められるだけの手続きを進めておくとスムーズに保険金を受け取れる。保険会社が不明なら大家さんなり管理会社なりに聞くしかない。私は翌朝を待って自分のスマホで連絡をした。

スマホが焼失した入居者は大家さん宅の電話を借りていた。契約によってはショップで代替機の入手も可能なようだ。俺はスマホが無事だったが、何かにつけて連絡手段は必要になるので、もしスマホが無ければ大変に面倒だったろう。スマホが無事で本当に良かった。

夜が明けてしばらくする頃にはほぼ消し止められた。それから現場検証が開始されたが、俺は避難先から出てそれを横で眺めることになった。理由は2つある。

1つ目は万が一に備えてコンピュータ機器のストレージだけは回収するため。さすがに使い物にならなくはなっているだろうが、セキュリティ上の懸念点は念には念を押して潰したかったためである。現場検証の邪魔になる瓦礫は火元の部屋から次から次へと消防士が運び出していく。私の部屋は火元の真上の2階だが、その床が焼け落ちており、かつて俺の部屋にあったものはすべて落下してしまっている。俺のPC・PS4・会社貸与ノートPC、これらがいつ運び出されるのか分からない。そのため、片付け作業を横で見る事にした。最終的に、これらは確保できた。また、会社貸与ノートPCは返却を要求されたので、黒焦げで異様な臭気を放つそれは返却した。確実に廃棄物だが会社管理のPCはその会社での廃棄が望ましいのだろう。

2つ目は現場検証に度々呼ばれたため。上述のとおり、火元の部屋にあったものと、その上階の俺の部屋にあったものとは、床が焼け落ちたことで混然一体となってしまっている。これらの判別が必要らしく、これは貴方のものかそうでないか、という確認が何度かされた。そのたびに大家さん宅から出向いたり消防士のデジカメを確認のために起き上がったりは面倒になった。それで1つ目の理由もあり横で見ている事にした。

現場検証。これはソフトウェア開発者が障害発生後に実施する原因調査に似ている。事後に収集できる情報、ログや関係者聞取りなど、から原因を推測するが、火災の現場検証も焼け跡や住民・目撃者の証言を基に原因を推測するようだ。たとえば、私は布団の所有者とその位置を何度か確認された。どうも火元の部屋は布団の下に電源コードがあり電気火災を疑っていたらしい。それで布団の所有者確認が重要のようだった。他にも、エアコンやその他の冷暖房器具、怪しい延長ケーブルも同様に確認を求められた。

この原因はこれこれの理由により99%ありえない、よって現実的にこの原因は無いとする。ソフトウェア開発の障害調査でも似たような絞り込みで仮説と検証を繰り返すので、火災の現場検証も似たような事をするのだろう。焼け跡という結果は一つだが、そこに至る原因は複数考えられる。よって、現実的にありえない確率の原因を一つ一つ潰して現実的に有り得る原因を絞り込む、という風に見えた。

現場検証は正午頃には終了した。検証結果は消防・警察など現場の関係者を集めて報告するというので、被害者の俺が聞く必要性は無いが、なんとなく大家さんと一緒に聞きに行く。原因はここでは詳述しない。これが終わると消防士たちは撤収していった。俺は深々と頭を下げて見送った。

そうこうするうち夕方が近付き今日の宿泊先を探す必要がある。大家さん宅に引き続き御厄介になる選択肢もあるが、スマホと財布が無事なら自力解決すべき、と判断した。大家さん宅こそ無事だがアパート一棟全焼で被害者でもある。先方とて何時までも他人が居ては落ち着かないだろう。スマホで近隣の宿泊可能なビジネスホテルを探して予約をする。

次は最低限の身の回り品を買い揃える。さすがにパジャマにサンダルで焦げ臭い匂いをまき散らしながら電車には乗れない。近所のスーパーで服・バッグ・靴・タオル等を購入、大家さん宅に戻り着替える。お世話になった大家さんにも深々と頭を下げて感謝を示し、ビジネスホテルへと移動する。

長い一日はまだ終わらない。明日以降の宿泊先をなんとかせねばならない。実家に一時的に戻る事を考えたが諸々の手続きはこちらに居ないと進まないのでこれは最終手段とした。賃貸物件を探して引っ越すにしてもそれまでどうするか。おおむね一か月は必要としてさすがにビジネスホテル連泊は環境的にも金銭的にも厳しい。そういうわけでマンスリーマンションを選択する。

初めてマンスリーマンションを利用するので知らなかったが即入居可能物件でも審査が必要なので翌日いきなり入居は出来ない。スマホとクレジットカードが無事な事がここでも効いてくる。申請は身分証明書をスマホで撮影してスマホで登録すれば完了する。あとは企業に素直に事情を話し近場でなるべく早く入居可能な物件を紹介してもらい適当なところに決めてしまう。入居まで数日必要なのでそれまで繋ぎとなるビジネスホテルも合わせて予約する。これで当面は雨風をしのげる算段は整った。

とっくに日も落ちてもうクタクタである。一息付くとようやく腹が減ってくる。今日は一日何も食べていない。近場にモスバーガーがあるのでテイクアウト。あたたかい食事が本当に染みる。

これで長い長い一日目が終了となる。

2日目

焼け跡の片付けを行う。私の部屋は天井と屋根が抜け落ちて文字通りの全焼で何も残っていないが、残存の可能性が高い耐火ケースはなるべく早く確保したかった。火事場泥棒という言葉もある。これの詳細については以下にまとめてあるので、興味のある方は参照して頂きたい。

ビジネスホテルで起床後にまずホームセンターへ向かい軍手・マスク・ショベルなど片付けに必要な物資を調達する。

ここで早くも保険会社から連絡が来る。今後の流れの説明を受け、調査員の現地訪問の日取りの約束をする。こちらの一報の翌日にはもう手続き開始可能なのか、と驚いたのを覚えている。

片付け、というより、耐火ケースの発掘を開始する。それが配置してあった位置から階下に落下したであろう地点に見当をつけて瓦礫を黙々と掘り出していく。ショベルで瓦礫をひたすら外に放り出すだけなので体力的にはそこまで負担は無いが、本当にここにあるのかどうか疑わしいまま単純作業を続けるのは精神的にキツかった。焼け跡の臭いも厳しい。マスク程度では防げない、異様な焦げ臭ささが、呼吸の度に鼻の奥まで侵入する。数日間こびりついたままなのが本当に辛かった。だから目的のものを掘り出せて、中身の無事が確認できた時は本当に心から安堵した。これでまた一つ生活復旧が楽になる。

ところで、このアパートはそれなりに人通りがある道に面しており、休憩しながらの作業で視界に通行人の様子が目に入る。たいていの人は足を止めて驚きの表情で見上げていく。複数人であれば「昨日の騒ぎはこれか」などとささやきあうのも聞こえてくる。足早に通り過ぎる者でもチラ見くらいはする。無遠慮にスマホを向ける無礼者もいる。

ながらスマホは一切のリアクションが無い。

もちろん詳細な観察をしたわけではないが、それなりの通行人にはそれなりの数のながらスマホが混じっているが、その大半はノーリアクションだった。

ながらスマホが主張するところの「視えている」とは、昨晩全焼したばかりの黒焦げ建造物が視界に入らず、多様な物資が燃えたゆえの焦げ臭さと大量の放水による湿り気が入り混じった異様な臭気にも気付かず、通行人が足を止めての会話も聞こえていない。つまり、少なくとも視覚・嗅覚・聴覚はかなり低下している。おそらく五感すべて同様の有様だろう。気配だとか雰囲気だとか、普段とは何かが違う、という事を察知出来ていない。警笛の鳴る踏切に立ち止まるのも無理は無い。住宅火災は恐ろしいが、ゾンビがその辺りをウロウロしている事に気付かされたのもまた恐ろしかった。

3日目

丸二日間も非日常的な活動をし続けると、さすがに興奮状態も収まり、疲労がどっと押し寄せてくる。にも関わらず両親が見舞いに訪問するという。はっきり入って心底迷惑だった。だが無碍に扱うわけにもいかない。普段の出勤と変わらない時間に起床すると重い身体を引きずるように駅へ迎えに行く。

当然何があったかを聞かれるので、警察・消防・役所に何回も何回も説明したのと同じ事「深夜未明の就寝時、異臭に気付いて目が覚めて……」をまた話しているとイライラして仕方が無い。火災現場に到着したらしたで、あれは何これは何、という話になるがその都度また似たような説明を繰り返させられる。被害者の俺がなんで解説役やらされてるんだ? 「引越と捉えて前向きに」だって? こっちは何の不都合も無い生活をいきなり追い出されたのに、1日2日でそんな境地に至れる訳が無い。

もし近しい人物が住宅火災になった場合、見舞いのタイミングは慎重に見極めるべきだ。身体的には何の問題が無くとも、精神的にはどうなのかは本人にすら良く分からない。受け入れ側に余裕が無い見舞いは危険だ。善意を断ったりキレ散らかすのは難しい。相手との関係性や距離感、特に相手の現在の状況を良く良く見極めた上での行動が望ましい。こんな事で人間関係に望まぬ亀裂が入るのは馬鹿馬鹿しい。もし、どうしても、火災直後に見舞いたいなら、金だけ渡して去るとか、片付け作業だけ手伝うとか、今すぐ役立つ即物的な行動だけに留めるのが無難だろう。生きてさえいれば、身体も精神も落ち着いた後、改めて場を設ければ良いだろう。期間の目安としては冒頭に書いた3週間もしくは3か月以降になるだろう。

爆発寸前だったのを何とか抑えて両親を見送るも気分が落ち込んで仕方が無かった。突然住宅を奪われた悲しみもだが、善意で訪問した両親に内心とはいえ八つ当たりする己もまたみじめだった。疲労困憊の極みだったが、身体を動かして気を紛らわせたくなった。頭の中がグチャグチャになっており無心で何らかの作業をしていたかった。

それで火災現場に戻り他入居者の片付け作業を手伝う事にした。俺の部屋は床が焼け落ちて何も残らなかったので、被害規模だけなら一番大きい。しかし、片付ける物が無いので全部諦めてそれで終わり。むしろ中途半端に焼け残っている方が大変である。まだ使える物が残ってる……かもしれない。一縷の望みをかけて片づけるも、強烈な匂いが残っていたり、放水でグショグショになりとても使い物にならなかったり、が大半である。それでも、多少臭うが洗濯を繰り返せばなんとかなりそうな衣類だとか、火災との位置関係やらバッグに守られたやらで財布やスマホや現金が無事だったりとか、残っている物は残っている。俺も引き出しに焼け残ったグショグショの硬貨・紙幣をいくらか回収しており、後に銀行へ交換しに行っている。

後で知った事だが、各居室の片付けは居住者の責任、物件そのものは大家の責任、となるらしい。居室を自力で片づけるか業者に依頼するかは人それぞれである。もっとも、焼け落ちた黒焦げに境界線を引けるわけもない。俺の場合、各居住者が残存物の整理をした後、大家さんが一括で業者に依頼したようだった。各居室ごとに費用が発生する。領収書は受領してないので費用の妥当性は良く分からない。なお、火災保険によってはこの片付け費用もカバー可能である。俺も請求可能だったが、大家さんに連絡して領収書の発行だとかが面倒だったのでこれの申請は諦めた。

この文章の冒頭で「日常は取り戻せる」と未来の同類に対して威勢よく書いたが、これは正確では無い。このアパートは大家さんが大らかなのか何なのか分からないが、小鳥を飼育している入居者が居た。サンダルどころか裸足で逃げ出す者すらいたので、鳥かごの持ち出しなど望むべくもない。当然、全滅である。真っ黒に焼け焦げ扉が閉じたままのケージには何も残っていない。

「死体が見つからない。墓も立ててやれない」

引っ越せば住む家はある。家具やら衣服やらパソコンやらは買いなおせば済む。だが、ペットは……買い直せても、ペットとの生活は取り戻せない。日常は買い直せるが、同じ日常は取り戻せない。他人にとっては些末なものでも、自分にとっては全くそうでないものほど取り戻せないのだ。俺とて同じ被害者だが、ペットの喪失感は想像も出来ない。自然死や病死ならいずれ終わる命と受け入れられるのかもしれないが、人の業で焼かれて心の整理はつくのだろうか? 俺は慰めの言葉一つ出せなかった。

俺とて思い出の品々は全滅である。大学時代のACM-ICPCで国内予選をギリギリ通過するも上位の化け物には全く敵わず打ちのめされた時の賞状、骨髄バンクドナーの返礼として受け取った幼児からの手紙、思い入れのある技術書やマンガなどの蔵書……すべて処分場の土の中である。

俗に放火は重罪と言われるが、他人の生活を突然破壊する行為の重大さ故なのだろう。生命がいともたやすく脅かされるのも大きいだろう。火中に取り残されれば死ぬし、煙に巻かれても死ぬ。放火だろうが失火だろうが、火災は人間の生活に対して一切の容赦は無い。

4日目

良くある悪夢の一つに、とっくに大学を卒業済みなのに単位不足で留年する、はちょくちょく耳にする。俺は後遺症は何も残らなかったが、嗅覚は今でも微妙な反応をする時がある。焼き鳥屋の前を通ると、炭火がおいしそうよりも前に、脳が警告を発する感覚がある。就寝時は特に顕著で、においに変化があると脳が即座に覚醒する。引っ越し後しばらくして夏場に窓開けて寝ていた時に近所の調理か何かのにおいが漂ってきて飛び起きた事がある。4日目では鼻の奥に以前として焦げ臭さがこびり付いており、ウトウトした時にこれを脳が異常と判断するのか何なのか、やはり飛び起きる事となる。

とにかく疲れ果てていた。

緊急時の興奮状態は持って2日せいぜい3日。完全休息日を3日目、遅くとも4日目には必ず取るべきだ。俺は飛び起きたりもしつつ、やはり身体的疲労は如何ともしがたく、昼過ぎまでグッタリし続けた。多少の空腹感があるので近所の喫茶店に出かけてモソモソと軽食を取る。ボンヤリとして何にもやる気が起きず、取り留めも無い事ばかりが頭に浮かんでは消えていく。

無事なスマホに改めて感謝しつつなんとなく小説家になろうお人好しが異世界で一旗揚げますんという作品を読み始める。この物語は、独特の善性を持つ主人公があれやこれや他者の手助けすると、それがあれよあれよという間に世界全体に波及し始め、最終的に世界がハッピーになるという、かなりハッピーなお話である。世界は必ず良い方向に移ろい流れていくものだ、という文字列を無心でただただ目で追い続けるのがこの時ばかりは心地よかった。

夕暮れが迫るとそれなりに空腹感が出てきたので思い切って大盛スタミナ丼を注文すると綺麗に食べ切れた。不思議なもので腹に余裕が出来ると気持ちにも余裕が出来る。なんとか頑張れそうな気がしてこの日は眠りにつく。

5日目

ビジネスホテルをチェックアウトしてマンスリーマンションへ移動する。生まれて初めてマンスリーマンションを利用したのだが、一通りの設備が整っている事に感動した。おそらく主な用途は仕事や旅行で一か月滞在と思われるが、手ぶらというか精々着替えさえあれば、すぐに当面の生活拠点に出来る。持ってるのは財布とスマホくらいの俺には持ってこいのサービスだった。

一旦は環境とか身体的および精神的疲労とかが落ち着いた。生活を取り戻していく上で今出来ることは何だろうか? と考える。

にわか知識だが、うつ病の典型的な症状として、今まで出来ていた事が出来なくなるという。これには様々な幅があり、趣味として楽しめていたものが急に冷めてしまうというものから、日常の入浴や掃除が出来なくなり生活が荒れるというものまである。家が燃えれば誰だって精神的ショックを受けるので、厳密には俺の置かれた状況をうつ病と呼ぶかは違うだろう。ただ、これを踏まえると、普段のルーチンを可能な限り取り戻した方が精神的には安定するのではないか、と考えた。

ドラッグストアやスーパーに立ち寄り色々と買い揃える。まずは歯磨き。俺は歯科治療に手を焼いた経験から毎日入念に歯磨きをする。デンタルフロスをしてシュミテクトの一番高いヤツで歯磨きをすると口腔内がスッキリする。ビジネスホテルのバスタブにお湯を張ってゆっくりと入浴をする。石鹸を泡立てて洗顔をし、T字カミソリであごひげを剃り落とす。風呂から上がるとニベアの化粧水と乳液を顔にすりこむ。軽くストレッチをする。

プロ野球選手が打席に立つ際にルーティンをこなす理由がなんとなく理解出来る。毎日欠かさずしている事をするとそれだけで気分が落ち着く。もちろん無理して取り戻そうとするのは危険だが、戻せそうな事は早めに戻していくのは重要ではないか。

6日目

保険会社の立ち合いのため火災現場に向かう。いつもの説明「深夜未明の就寝時、異臭に気付いて目が覚めて……」をすると焼け跡の調査が始まるが、私の居室は天井と床が抜けているので見るものが無い。これが一般的な調査なのかどうかは分からないが、2,3の質問をされたり、各所を撮影したり、ぐらいで淡々と終了した。

今後の流れの説明を受ける。大きくは消防署からり災証明書を発行してもらうのと、損害品明細書の作成、郵送となる。前者は消防署からの連絡待って受取に出向くだけだが、後者が問題となる。詳細は「損害品明細書」で画像検索でもすればイメージは掴めるが、家財の名称・メーカー名品番など・所有者・数量・購入単価・購入先・購入年月日・領収書などの有無、を記載する。

これの作成は一人暮らしでも中々に大変である。まず、部屋のレイアウトと家具配置を思い出せる限り紙に書き出していく。これがここにあって、あれはそこにあって、押し入れにはあれとそれが収納してあって……おおよそのリストが出来たらおおまかなカテゴリー別、家電・家具・服・本、とざっくり分類して抜け漏れが思い出せないかどうかを試す。それからネットカフェへ向かい、ヨドバシカメラamazon楽天などのECサイトにログインし、領収書のPDFをダウンロードして印刷する。同時にそれなりに高額品の抜け漏れが無いかも確認する。これらは1日でこなしたわけでは無く、諸所の作業の合間などで数日かけて作成した。

可能であれば、googleスプレッドシートなどオンライン上に明細を作成しておくのをオススメする。高額品の購入時にだけリスト更新するならさほど手間でも無いし、保険申請の備えとしては重要度は高い。領収書のPDFも同時にオンラインストレージに保管しておくとなお良いだろう。

午前中に立ち合いを済ませた後、午後は不動産会社へ向かう。その前に、ネットカフェで賃貸物件をあらかじめ目星をつけておく。条件は即入居が絶対条件。次に、生活環境を変えたくなかったので、以前と同一の最寄り駅にする。あとは風呂トイレは別にしたいだとか個人的な好みを加えると、引っ越しシーズンでは無いので、候補はせいぜい2,3件。google地図とストリートビューで最寄り駅までのルートのイメージやら周辺のスーパーやコンビニなどとの位置関係やらも合わせてチェックしておく。

不動産屋も火災は当然把握しているので、元住民の俺には優先して対応してくれた。まずは形式上は退去届が必要なので記入だとかあれやこれや書類に記入していく。事前に目星をつけておいた賃貸物件を見せ、他に適当な物件が無いかを探してもらう。下見の予約をする。

ちなみに、これは後日聞いた話になるが、一般的に賃貸物件の大家・管理会社は即入居の要求はやや警戒するものらしい。引っ越しシーズンでも無いのに急かす理由は何なんだ、という理屈のようだ。ただ、ここは不動産会社が間に入り、火災で焼失したとか、家賃の支払いなどトラブルは無かったとか、を保証してくれたので特に何事も無かった。

7日目以降

それから数日後に下見を行い引っ越し先を決めて契約手続きを行う。ここまで来ると一般的な引っ越しとほとんどやる事は変わらない。もっとも、あらゆる物資をゼロから購入しなおす点は異なるが。入居日が確定したらスマホ・ネットカフェで家具やらパソコンやら生活用品やらをヨドバシカメラニトリなどで数万数十万の購入をして、不正使用疑いの通知が来たのを覚えている。

最初に書いた通り全焼から3週間後に職場復帰している。引っ越し先のカギを受け取ったらマンスリーマンションと往復して、注文品を受け取ったりライフライン開通の手続きをする。近所のスーパー・ドラッグストアで細々とした生活用品を買い直す。皿一枚靴下一足から買い直すので後から後からあれが足りないこれが足りないとなり中々に大変だった。マンスリーマンションの契約が終了する頃にはおおよその新生活の準備を済ませので、出勤したら契約終了手続きをし、勤務終了したら引っ越し先へと帰宅する。

この間に各種の手続きを可能な限り済ませているが、ほとんどはおそらく通常の引越と変わらないだろう。もちろん火災関連は異なり、消防署からり災証明書の準備完了の連絡が来たら受取に向かい、火災保険の申請のための損害品明細書を作成して郵送している。おおよそ2週間程度で先方から見積が来てOKすると保険金が振り込まれる。なお、り災証明書は何通かコピーを取得しておいた方が良い。火災保険申請など重要な手続きは原本が必要だが、その他のではコピーの確認・提出で十分な事が多いためである。

他の各種手続きとしては、転居届(同一区内)・郵便の転送届・免許証とマイナンバーカードの住所変更、など。俺は財布内の身分証明書や金融機関の通帳・印鑑が無事だったのでその辺りの再発行は省略できた。

3か月も経つ頃には生活はほぼ元通りである。

おわりに

生きてて良かった、としか言い様がない。生活の復旧はとんでもなく苦労したが生きてさえいればなんとでもなる。

住宅が全焼した事のない幸運な方にはインターネットの数多なオモシロ文章の一つとして楽しんで頂けたなら幸いだし、不運にも住宅火災に巻き込まれた方には何らかの参考なり慰めなりになれば幸いである。