# Business Logic — FUW02001SFLogic.checkException() [113 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.FUW02001SF.FUW02001SFLogic` |
| Layer | Service (Package: `eo.web.webview.FUW02001SF`, extends `JCCWebBusinessLogic`) |
| Module | `FUW02001SF` (Email Address Settings Registration — Mail Forwarding / Email Address Change) |

## 1. Role

### FUW02001SFLogic.checkException()

This method is a centralized exception classification and routing handler for the **Email Address Settings Registration** screen (FUW02001). It receives a `JCCWebServiceException` object — which was thrown during a prior business operation — and a `callMethod` string that indicates whether the user pressed the **confirmation button** (`cfm`) or the **registration button** (`mskm`). The method inspects the exception's metadata (template ID, error flag, item ID, status) and determines which specific **business error** or **system error** should be surfaced back to the user. It implements a **conditional dispatch pattern**: if the exception status indicates a "relation error" (status = `1100`, meaning a cross-field or cross-service consistency check failed), the method evaluates the error flag + item ID combination to map it to a precise, user-facing error message. For relation errors, the confirmation button path re-throws the original web service exception (allowing the UI to display the original validation details), while the registration button path converts the exception into a specific `JCCBusinessException` with a standardized error code (e.g., contract status error, update-not-possible error, usage limit error). If the status is anything other than a relation error, the method falls through to a default system error. This method is the **single entry point** for exception translation in the FUW02001SF email address registration workflow.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["checkException(JCCWebServiceException se, String callMethod)"])
    GET_MSG["Extract status, errFlg, itemid, templateid from exception"]
    CHECK_REL_STATUS{status == RELATION_ERR}
    CHECK_MODE{callMethod == cfm}
    CHECK_REG_ERR_EH{"EKK0411D010 AND EH AND op_svc_kei_no"}
    THROW_WEB_EX["throw se Business Exception"]
    CHECK_REG_ERR_EI{"EKK0411D010 AND EI AND op_svc_kei_no"}
    CHECK_CHG_ERR_EF{"EKK0411C010 AND EF AND sbop_svc_kei_no"}
    CHECK_CHG_ERR_EG{"EKK0411C010 AND EG AND sbop_svc_kei_no"}
    CHECK_TS_EA_D{"EKK0411D010 AND EA AND upd_dtm_bf"}
    CHECK_OPS_CNF_EH{"EKK0411C010 AND EH AND sbop_svc_kei_no"}
    CHECK_TS_EA_C{"EKK0411C010 AND EA AND upd_dtm_bf"}
    THROW_SYST_0102["throw JCCBusinessException ERROR_CODE_0102 Contract Status Error"]
    THROW_SYST_0204["throw JCCBusinessException ERROR_CODE_0204 Update Error"]
    THROW_SYST_0101["throw JCCBusinessException ERROR_CODE_0101 Usage Limit Error"]
    THROW_DEFAULT["throw JCCBusinessException ERROR_CODE_0002 System Error"]
    END_NODE(["Return / Next"])

    START --> GET_MSG
    GET_MSG --> CHECK_REL_STATUS
    CHECK_REL_STATUS -->|Yes| CHECK_MODE
    CHECK_REL_STATUS -->|No| THROW_DEFAULT
    CHECK_MODE -->|cfm| CHECK_REG_ERR_EH
    CHECK_MODE -->|mskm| CHECK_REG_ERR_EH_S
    CHECK_REG_ERR_EH -->|match| THROW_WEB_EX
    CHECK_REG_ERR_EH -->|no| CHECK_REG_ERR_EI
    CHECK_REG_ERR_EI -->|match| THROW_WEB_EX
    CHECK_REG_ERR_EI -->|no| CHECK_CHG_ERR_EF
    CHECK_CHG_ERR_EF -->|match| THROW_WEB_EX
    CHECK_CHG_ERR_EF -->|no| CHECK_CHG_ERR_EG
    CHECK_CHG_ERR_EG -->|match| THROW_WEB_EX
    CHECK_CHG_ERR_EG -->|no| CHECK_REG_ERR_EH
    CHECK_REG_ERR_EH_S -->|match| THROW_SYST_0102
    CHECK_REG_ERR_EH_S -->|no| CHECK_REG_ERR_EI_S
    CHECK_REG_ERR_EI_S -->|match| THROW_SYST_0102
    CHECK_REG_ERR_EI_S -->|no| CHECK_CHG_ERR_EF_S
    CHECK_CHG_ERR_EF_S -->|match| THROW_SYST_0102
    CHECK_CHG_ERR_EF_S -->|no| CHECK_CHG_ERR_EG_S
    CHECK_CHG_ERR_EG_S -->|match| THROW_SYST_0102
    CHECK_CHG_ERR_EG_S -->|no| CHECK_TS_EA_D
    CHECK_TS_EA_D -->|match| THROW_SYST_0204
    CHECK_TS_EA_D -->|no| CHECK_OPS_CNF_EH
    CHECK_OPS_CNF_EH -->|match| THROW_SYST_0101
    CHECK_OPS_CNF_EH -->|no| CHECK_TS_EA_C
    CHECK_TS_EA_C -->|match| THROW_SYST_0204
    CHECK_TS_EA_C -->|no| THROW_DEFAULT
```

**Constant Resolution Reference:**

| Constant | Value | Business Meaning |
|----------|-------|------------------|
| `JPCModelConstant.RELATION_ERR` | `1100` | Cross-field / cross-service consistency check failure |
| `CALL_METHOD_CFM` | `"cfm"` | Confirmation button mode |
| `CALL_METHOD_MSKM` | `"mskm"` | Registration button mode |
| `EKK0411D010` | `"EKK0411D010"` | Sub-optional service contract (ISP) registration |
| `EKK0411C010` | `"EKK0411C010"` | Sub-optional service contract (ISP) change |
| `JFUStrConst.RELATION_CHECK_ERR_EH` | `"EH"` | Business error - registration |
| `JFUStrConst.RELATION_CHECK_ERR_EI` | `"EI"` | Business error - registration (2nd error type) |
| `JFUStrConst.RELATION_CHECK_ERR_EF` | `"EF"` | Business error - change |
| `JFUStrConst.RELATION_CHECK_ERR_EG` | `"EG"` | Business error - change (2nd error type) |
| `JFUStrConst.RELATION_CHECK_ERR_EA` | `"EA"` | System error - update-not-possible |
| `OP_SVC_KEI_NO` | `"op_svc_kei_no"` | Optional service contract number |
| `SBOP_SVC_KEI_NO` | `"sbop_svc_kei_no"` | Sub-optional service contract number |
| `UPD_DTM_BF` | `"upd_dtm_bf"` | Update timestamp (before) |
| `ERROR_CODE_0102` | `"0102"` | Contract status error |
| `ERROR_CODE_0204` | `"0204"` | Update-not-possible error |
| `ERROR_CODE_0101` | `"0101"` | Usage limit error |
| `ERROR_CODE_0002` | `"0002"` | System error (default fallback) |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `se` | `JCCWebServiceException` | The exception object thrown during a prior service call. Contains structured metadata (`templateId`, `itemId`, `status`, `itemCheckErr`) extracted from the `X31CMessageMoreInfo` list — this metadata identifies exactly which field and which service template triggered the failure. It is the **input payload** for the exception classification logic. |
| 2 | `callMethod` | `String` | Indicates which button the user pressed to initiate the operation: `"cfm"` (confirmation button — review mode, where the system displays original validation errors back to the user) or `"mskm"` (registration button — submission mode, where the system converts relation errors into user-friendly system error codes). This parameter determines the **error routing path** (web exception vs. business exception). |

**Instance Fields / External State Read:**
| Field | Type | Business Description |
|-------|------|---------------------|
| (none read directly) | — | This method reads no instance fields; it operates solely on the parameter `se` and local variables. All constant values are resolved at runtime from static final fields defined in the class and shared constant classes. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `se.getMessageList` | — | — | Extracts the message list from the passed `JCCWebServiceException` (metadata query, not a database call). |
| R | `msgResult.getMessageMoreInfoList` | — | — | Retrieves the `X31CMessageMoreInfo[]` array containing error detail objects. |
| R | `info.getTemplateId` | — | — | Reads the template ID (SC code identifier) from the error metadata. |
| R | `info.getItemId` | — | — | Reads the item ID (field name) that triggered the error. |
| R | `info.getStatus` | — | — | Reads the status code to check if it is a relation error (`1100`). |
| R | `info.getItemCheckErr` | — | — | Reads the error flag code (EH, EI, EF, EG, EA) that classifies the error type. |
| — | `throw se` | — | — | Re-throws the original `JCCWebServiceException` (used in confirmation mode; no service call). |
| — | `new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | — | — | Creates and throws a business exception for contract status error (registration button mode). |
| — | `new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` | — | — | Creates and throws a business exception for update-not-possible error. |
| — | `new JCCBusinessException(JFUStrConst.ERROR_CODE_0101)` | — | — | Creates and throws a business exception for usage limit error. |
| — | `new JCCBusinessException(JFUStrConst.ERROR_CODE_0002)` | — | — | Creates and throws a default system error (fallback for non-relation errors or unmatched conditions). |

**Note:** This method is a **pure exception classifier** — it does not invoke any SC/CBS service components or perform database operations. It consumes metadata from the `JCCWebServiceException` parameter and re-throws either the original exception (in confirmation mode) or a `JCCBusinessException` with a resolved error code (in registration mode).

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

Direct callers: 2 methods, all internal to `FUW02001SFLogic`.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Internal: `FUW02001SFLogic.cfm()` | `cfm()` -> `checkException(se, CALL_METHOD_CFM)` | `se.getMessageList [R]`, `JCCBusinessException [ERROR_CODE_0102/0204/0101/0002]` |
| 2 | Internal: `FUW02001SFLogic.mskm()` | `mskm()` -> `checkException(se, CALL_METHOD_MSKM)` | `se.getMessageList [R]`, `JCCBusinessException [ERROR_CODE_0102/0204/0101/0002]` |

**Caller Details:**

- **`cfm()`** — The confirmation button handler. Called when the user clicks the **confirmation** button on the email address settings screen. Passes `CALL_METHOD_CFM` (`"cfm"`) as the callMethod parameter. In this path, the method re-throws the original `JCCWebServiceException` for the identified registration error combinations, preserving the original error message for display.

- **`mskm()`** — The registration button handler. Called when the user clicks the **registration** button on the email address settings screen. Passes `CALL_METHOD_MSKM` (`"mskm"`) as the callMethod parameter. In this path, the method converts relation errors into specific `JCCBusinessException` instances with error codes 0102, 0204, 0101, or 0002, providing user-friendly error messages.

## 6. Per-Branch Detail Blocks

**Block 1** — [ASSIGNMENT/UNPACKING] (L721–L727)

> Extract error metadata from the `JCCWebServiceException`. The Japanese comment says: "取得例外情報" (Retrieve exception information).

| # | Type | Code |
|---|------|------|
| 1 | SET | `msgResult = se.getMessageList()` | // Retrieve exception message list |
| 2 | SET | `moreInfo = msgResult.getMessageMoreInfoList()` | // Retrieve more info array |
| 3 | SET | `info = moreInfo[0]` | // Take first entry (Japanese: 関連チェック系は必ずエラーが1つのため0番目から取得する — "Related check always has exactly one error, so read from index 0") |
| 4 | SET | `templateid = info.getTemplateId()` | // Template ID identifying which SC triggered the error |
| 5 | SET | `itemid = info.getItemId()` | // Field/item ID that triggered the error |
| 6 | SET | `status = info.getStatus()` | // Status code to check error category |
| 7 | SET | `errFlg = info.getItemCheckErr()` | // Error flag code (EH, EI, EF, EG, EA) |

**Block 2** — [IF] `(status == JPCModelConstant.RELATION_ERR = "1100")` [CONSTANT: `JPCModelConstant.RELATION_ERR = "1100"`] (L729)

> The Japanese comment says: "エラーを判定" (Determine error) and "関連チェック" (Related check). This outer block handles all relation (cross-field/cross-service consistency) errors.

**Block 2.1** — [IF] `(CALL_METHOD_CFM = "cfm" == callMethod)` [CONSTANT: `CALL_METHOD_CFM = "cfm"`] (L732)

> The Japanese comment says: "確認ボタン押下時" (When confirmation button is pressed). This path handles the **confirmation button** mode — the system preserves the original web service exception for UI display.

**Block 2.1.1** — [IF] `(templateid == "EKK0411D010" AND errFlg == "EH" AND itemid == "op_svc_kei_no")` [CONSTANT: `EKK0411D010 = "EKK0411D010"`, `JFUStrConst.RELATION_CHECK_ERR_EH = "EH"`, `OP_SVC_KEI_NO = "op_svc_kei_no"`] (L739)

> The Japanese comment says: "登録時" (At registration) and "EKK0411D010_サブオプションサービス契約<ISP>登録 / NGワードチェック" (EKK0411D010 Sub-optional Service Contract (ISP) Registration / NG word check). When the sub-optional ISP registration template fails with error flag EH on the optional service contract number field.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw se` | // Re-throw original web exception (Japanese: 業務エラー例外クラスをthrow — "Throw business error exception class") |

**Block 2.1.2** — [IF] `(templateid == "EKK0411D010" AND errFlg == "EI" AND itemid == "op_svc_kei_no")` [CONSTANT: `JFUStrConst.RELATION_CHECK_ERR_EI = "EI"`] (L746)

> The Japanese comment says: "エイジングチェック" (Aging check). When the registration template fails with error flag EI on the optional service contract number field.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw se` | // Re-throw original web exception |

**Block 2.1.3** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EF" AND itemid == "sbop_svc_kei_no")` [CONSTANT: `EKK0411C010 = "EKK0411C010"`, `JFUStrConst.RELATION_CHECK_ERR_EF = "EF"`, `SBOP_SVC_KEI_NO = "sbop_svc_kei_no"`] (L754)

> The Japanese comment says: "変更時" (At change) and "EKK0411C010_サブオプションサービス契約<ISP>変更 / NGワードチェック" (EKK0411C010 Sub-optional Service Contract (ISP) Change / NG word check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw se` | // Re-throw original web exception |

**Block 2.1.4** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EG" AND itemid == "sbop_svc_kei_no")` [CONSTANT: `JFUStrConst.RELATION_CHECK_ERR_EG = "EG"`] (L761)

> The Japanese comment says: "エイジングチェック" (Aging check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw se` | // Re-throw original web exception |

**Block 2.2** — [ELSE] (callMethod != "cfm", i.e., "mskm" — registration button) (L767)

> The Japanese comment says: "申込むボタン押下時" (When registration button is pressed). This path converts relation errors into specific business exceptions with user-friendly error codes.

**Block 2.2.1** — [IF] `(templateid == "EKK0411D010" AND errFlg == "EH" AND itemid == "op_svc_kei_no")` (L772)

> The Japanese comment says: "登録時" (At registration) and "EKK0411D010_サブオプションサービス契約<ISP>登録 / NGワードチェック" (NG word check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | // System error - Contract Status Error (Japanese: システムエラーをthrow（契約状態エラー）) |

**Block 2.2.2** — [IF] `(templateid == "EKK0411D010" AND errFlg == "EI" AND itemid == "op_svc_kei_no")` (L780)

> The Japanese comment says: "エイジングチェック" (Aging check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | // System error - Contract Status Error |

**Block 2.2.3** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EF" AND itemid == "sbop_svc_kei_no")` (L788)

> The Japanese comment says: "変更時" (At change) and "EKK0411C010_サブオプションサービス契約<ISP>変更 / NGワードチェック" (NG word check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | // System error - Contract Status Error |

**Block 2.2.4** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EG" AND itemid == "sbop_svc_kei_no")` (L796)

> The Japanese comment says: "エイジングチェック" (Aging check).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | // System error - Contract Status Error |

**Block 2.3** — [IF] `(templateid == "EKK0411D010" AND errFlg == "EA" AND itemid == "upd_dtm_bf")` [CONSTANT: `JFUStrConst.RELATION_CHECK_ERR_EA = "EA"`] (L803)

> The Japanese comment says: "タイムスタンプチェック" (Timestamp check). Checks if the update timestamp (before) doesn't match, meaning the data was modified by another user — a concurrency conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` | // System error - Update-not-possible error (Japanese: システムエラーをthrow（更新不可エラー）) |

**Block 2.4** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EH" AND itemid == "sbop_svc_kei_no")` (L810)

> The Japanese comment says: "オプション契約上限チェック" (Optional service contract upper limit check). Checks if the number of optional services has exceeded the allowed limit.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0101)` | // System error - Usage Limit Error (Japanese: システムエラーをthrow（利用制限エラー）) |

**Block 2.5** — [IF] `(templateid == "EKK0411C010" AND errFlg == "EA" AND itemid == "upd_dtm_bf")` (L817)

> The Japanese comment says: "タイムスタンプチェック" (Timestamp check). Same concurrency check as Block 2.3 but for the change template.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` | // System error - Update-not-possible error |

**Block 3** — [EXCEPTION FALLTHROUGH] (L824)

> The Japanese comment says: "上記以外の場合システムエラーをスロー" (In all other cases, throw system error). If the status is not `RELATION_ERR` (1100), or if none of the specific error flag/item combinations matched within the relation error block, this line throws a default system error.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002)` | // Default system error — covers non-relation errors and unmatched relation error combinations |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `FUW02001SF` | Module | Email Address Settings Registration — the module for configuring email forwarding / mail alias settings for customers |
| `JCCWebServiceException` | Exception | A web service exception carrying structured error metadata (template ID, item ID, status code, error flag) from prior validation or business processing |
| `JCCBusinessException` | Exception | A standard business/system exception thrown with a numeric error code for user-facing error messages |
| `JPCModelConstant.RELATION_ERR` | Constant (`1100`) | Status code indicating a cross-field or cross-service consistency check failure (relation error) |
| `RELATION_ERR` | Business term | Cross-field / cross-service consistency error — occurs when dependent fields or services have incompatible values |
| `CALL_METHOD_CFM` | Constant (`"cfm"`) | Confirmation button mode — the user is reviewing data before final submission |
| `CALL_METHOD_MSKM` | Constant (`"mskm"`) | Registration button mode — the user is submitting the registration for final processing |
| `EKK0411D010` | Constant | Sub-optional service contract (ISP) registration — SC code for adding optional ISP services |
| `EKK0411C010` | Constant | Sub-optional service contract (ISP) change — SC code for modifying existing optional ISP services |
| `RELATION_CHECK_ERR_EH` | Constant (`"EH"`) | Error flag for business errors during registration (NG word check) |
| `RELATION_CHECK_ERR_EI` | Constant (`"EI"`) | Error flag for business errors during registration (aging check) |
| `RELATION_CHECK_ERR_EF` | Constant (`"EF"`) | Error flag for business errors during change (NG word check) |
| `RELATION_CHECK_ERR_EG` | Constant (`"EG"`) | Error flag for business errors during change (aging check) |
| `RELATION_CHECK_ERR_EA` | Constant (`"EA"`) | Error flag for system errors (update-not-possible / timestamp mismatch) |
| `op_svc_kei_no` | Field | Optional service contract number — the internal identifier for an optional service line item |
| `sbop_svc_kei_no` | Field | Sub-optional service contract number — the internal identifier for a sub-optional service line item |
| `upd_dtm_bf` | Field | Update timestamp (before) — used for optimistic concurrency control; if the stored timestamp does not match the value sent by the client, a concurrency conflict is detected |
| `ERROR_CODE_0101` | Constant (`"0101"`) | Usage limit error — the number of optional services has exceeded the maximum allowed |
| `ERROR_CODE_0102` | Constant (`"0102"`) | Contract status error — the contract is in a state that prevents the requested operation |
| `ERROR_CODE_0204` | Constant (`"0204"`) | Update-not-possible error — data was modified by another user since it was loaded (optimistic lock conflict) |
| `ERROR_CODE_0002` | Constant (`"0002"`) | Default system error — used as a catch-all for unexpected error conditions |
| NGワードチェック | Business term | NG word check — validation that checks for prohibited or invalid values in field inputs (Japanese: NGワード = "NG word", i.e., invalid/blacklisted values) |
| エイジングチェック | Business term | Aging check — a business rule check that verifies the age or timing of data (Japanese: エイジング = "aging") |
| タイムスタンプチェック | Business term | Timestamp check — verifies data has not been modified by another user since it was loaded (optimistic locking) |
| オプション契約上限チェック | Business term | Optional service contract upper limit check — verifies the customer has not exceeded the maximum number of allowed optional services |
| 契約状態エラー | Business term | Contract status error — the contract is in a state that prevents the requested operation |
| 利用制限エラー | Business term | Usage limit error — the customer has exceeded their allowed service usage |
| 更新不可エラー | Business term | Update-not-possible error — the data has been modified by another user |
| 確認ボタン | Business term | Confirmation button — the button the user clicks to review data before final submission |
| 申込むボタン | Business term | Registration button — the button the user clicks to submit the registration for final processing |
| サブオプションサービス契約 | Business term | Sub-optional service contract — an optional/add-on service contract line item (ISP = Internet Service Provider) |
| `X31CMessageMoreInfo` | Class | Metadata object carrying structured error information: template ID, item ID, status, and error flag |
