Skip to content

feat(plugin): add error-page plugin#13380

Open
AlinsRan wants to merge 11 commits into
masterfrom
feat/error-page-plugin
Open

feat(plugin): add error-page plugin#13380
AlinsRan wants to merge 11 commits into
masterfrom
feat/error-page-plugin

Conversation

@AlinsRan
Copy link
Copy Markdown
Contributor

@AlinsRan AlinsRan commented May 17, 2026

Summary

This PR introduces the error-page plugin, which allows customizing the response body and content type for HTTP error responses generated by APISIX itself (e.g., when no route matches or when the upstream is unreachable). Responses from upstream services are not intercepted.

Configuration

The plugin is configured via plugin metadata (global config, no per-route attributes needed). Set enable: true and configure one or more status codes:

{
    "enable": true,
    "error_404": {
        "body": "<html><body><h1>404 - Not Found</h1></body></html>",
        "content_type": "text/html"
    },
    "error_500": {
        "body": "{\"code\": 500, \"message\": \"Internal Server Error\"}",
        "content_type": "application/json"
    }
}

Key design points

  • Supported status codes: error_404, error_500, error_502, error_503 with built-in default HTML pages
  • Global on/off: controlled by enable in plugin metadata (default: false)
  • Custom content-type: each status code can have its own body and content_type
  • Upstream responses unaffected: only APISIX/nginx-generated error responses (where upstream_status is not set) are intercepted
  • Graceful fallback: if enable is false or no custom page is configured for a status code, the default nginx error page is used
  • Opt-in plugin: not enabled by default; users must add it to their conf/config.yaml

Changes

  • apisix/plugins/error-page.lua: plugin implementation
  • conf/config.yaml.example: add error-page as a commented-out opt-in entry
  • t/plugin/error-page.t: 18 test cases
  • docs/en/latest/plugins/error-page.md: English documentation
  • docs/zh/latest/plugins/error-page.md: Chinese documentation
  • docs/en/latest/config.json: add to sidebar under Transformation
  • docs/zh/latest/config.json: add to sidebar under Transformation

The error-page plugin customizes the HTTP error response body and
content type for APISIX-generated error responses. It uses plugin
metadata for global configuration and intercepts error responses
generated by APISIX itself (e.g., no matching route, unreachable
upstream), leaving upstream-generated responses unaffected.

Key features:
- Global on/off switch via `enable` in plugin metadata
- Supports any HTTP status code via patternProperties (100-599)
- Configurable response body and content-type per status code
- Falls back to default nginx/APISIX error page when not configured

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. doc Documentation things enhancement New feature or request plugin labels May 17, 2026
AlinsRan and others added 6 commits May 18, 2026 04:37
- Use response_body_like eval qr// to avoid trailing newline issue
  with lookahead patterns in Test::Nginx response_body_like blocks
- Fix docs/zh/latest/config.json sidebar entry (label is '转换请求')

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The plugin list in apisix/cli/config.lua is the authoritative default
plugin list used at runtime. Adding error-page between datadog and lago
matches the priority ordering.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The enable flag required users to explicitly set enable=true after
configuring error pages, which was redundant and unintuitive. The
plugin now intercepts errors as long as a matching error_XXX entry
with a non-empty body exists in the metadata. To disable, delete
the metadata or remove the plugin from the global rule.

Update tests and docs accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
error-page requires metadata configuration to be useful, so it should
be opt-in. Keep it in cli/config.lua as a known plugin but comment it
out in config.yaml.example and config-default.yaml.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove error-page from the default plugin list in cli/config.lua
so the plugin is not loaded unless the user explicitly adds it to
their conf/config.yaml.

Restore conf2/config-default.yaml - error-page should not appear
there at all (not even commented out).

Remove error-page from t/admin/plugins.t expected list since it is
no longer in the default plugin set.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file does not exist in the upstream apache/apisix repository
and should not have been added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 12 comments.

Comment thread apisix/plugins/error-page.lua
Comment thread apisix/plugins/error-page.lua
Comment thread apisix/plugins/error-page.lua Outdated
Comment thread apisix/plugins/error-page.lua
Comment thread t/plugin/error-page.t
Comment thread docs/en/latest/plugins/error-page.md
Comment thread docs/en/latest/plugins/error-page.md Outdated
Comment thread apisix/plugins/error-page.lua
Comment thread docs/zh/latest/plugins/error-page.md Outdated
Comment thread apisix/plugins/error-page.lua
Foo Bar and others added 4 commits May 20, 2026 13:43
- Fix upstream_status check: treat empty string and "-" as not set
  to avoid false-positive on APISIX-generated errors
- Restrict metadata schema to 4xx/5xx (400-599) matching runtime behavior
- Add additionalProperties=false to route/service schema
- Change noisy per-request info logs to debug level
- Add content_type fallback to "text/html" when schema default is not
  applied at runtime
- Call core.response.clear_header_as_body_modified() before overriding
  body to clear Content-Encoding/ETag headers
- Add TEST 17-18: verify upstream 500 responses are not intercepted
- Add canonical link to English and Chinese plugin docs
- Add "error-page" to English doc keywords
- Update supported status code range in docs: 100-599 -> 400-599

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove additionalProperties=false from schema (match EE behavior)
- Change "not defined" debug log back to info (tests 9/11 depend on it)
- Remove error_log assertions from TEST 9/11 that checked for a debug
  message not visible at info log level
- Use response_body_like in TEST 18 for robustness

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Sync metadata_schema with EE: use fixed properties for error_404/500/502/503
  with default HTML templates, and add enable flag (default: false)
- Use plain openresty format for default error page templates
- Revert upstream_status check to simple truthiness (APISIX-generated
  errors always have nil upstream_status, not empty string)
- Remove clear_header_as_body_modified() (not needed since APISIX-generated
  errors never have Content-Encoding set)
- Remove content_type fallback (schema defaults handle it)
- Update tests to include enable:true in metadata
- Update docs to reflect new schema structure

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…plate

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc Documentation things enhancement New feature or request plugin size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants