Skip to content

Commit b4808a0

Browse files
committed
Merge pull request rust-lang#65 from pangratz/publicize-log-levels
Deprecation warning handlers
2 parents efb2936 + b080be3 commit b4808a0

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
- Start Date: 2015-06-30
2+
- RFC PR: https://github.com/emberjs/rfcs/pull/65
3+
- Ember Issue: (leave this empty)
4+
5+
# Summary
6+
7+
Deprecations and warnings in Ember.js should have configurable runtime handlers.
8+
This allows default behavior (logging, raise when `RAISE_ON_DEPRECATION` is true)
9+
to be overridden by an enviornment (Ember's tests), addon, or other tool
10+
(like the Ember Inspector).
11+
12+
Ember-Data and the Ember Inspector have both requested a public
13+
API for changing how deprecation and warning messages are handled. The requirements
14+
for these and other requests are complex enough that deferring the message
15+
behavior into a runtime hook is the suggested path.
16+
17+
# Motivation
18+
19+
`Ember.deprecate` and `Ember.warn` usually log messages. With `ENV.RAISE_ON_DEPRECATION`
20+
all deprecations will throw an exception. In some scenarios, this
21+
is less than ideal:
22+
23+
* Ember itself needs a way to silence some deprecations before their usage
24+
is completely removed from tests. For example, many view APIs in Ember 1.13.
25+
* The Ember inspector desires to raise on specific deprecations, or silence
26+
specific deprecations.
27+
* Ember-Data also desires to silence some deprecations in tests
28+
29+
In [PR #1141](https://github.com/emberjs/ember.js/pull/11419)
30+
a private log level API has been introduced, which allows finer grained control
31+
if specific deprecations should be logged, throwing an error or be silenced
32+
completely. For example:
33+
34+
```js
35+
Ember.Debug._addDeprecationLevel('my-feature', Ember.Debug._deprecationLevels.LOG);
36+
// ...
37+
Ember.deprecate("x is deprecated, use Y instead", false, { id: 'my-feature' });
38+
```
39+
40+
Initially a public version of this API was discussed, but it quickly became
41+
clear that a runtime hook provided more flexibility without incurring the
42+
cost of a complex log-level API.
43+
44+
Note that "runtime" refers to Ember itself. A custom handler could be injected
45+
into Ember-CLI's template compilation code. "runtime" in this context still
46+
refers to handling deprecations raised during compilation.
47+
48+
# Detailed design
49+
50+
A handler for deprecations can be registered. This handler will be called
51+
with relevent information about a deprecation, including guarantees about
52+
the presence of these items:
53+
54+
* The deprecation message
55+
* The version number where this deprecation (and feature) will be removed
56+
* The "id" of this deprecation, a stable identifier independent of the message
57+
58+
Additionally, an application instance may be passed with the options. An example
59+
handler would look like:
60+
61+
```js
62+
import { registerHandler } from "ember-debug/deprecations";
63+
64+
registerHandler(function deprecationHandler(message, options) {
65+
// * message is the deprecation message
66+
// * options.until is the version this deprecation will be removed at
67+
// * options.id is the canonical id for this deprecation
68+
if (options.until === "2.4.0") {
69+
throw new Error(message);
70+
} else {
71+
console.log(message);
72+
}
73+
});
74+
```
75+
76+
Warnings are similar, but will not recieve an `until` value:
77+
78+
```js
79+
import { registerHandler } from "ember-debug/warnings";
80+
81+
registerHandler(function warningHandler(message, options) {
82+
// * message is the warning message
83+
// * options.id is the canonical id for this warning
84+
if (options.id !== 'view.rerender-on-set') {
85+
console.log(message);
86+
}
87+
});
88+
```
89+
90+
##### chained handlers
91+
92+
Since several handlers may be registered, a method of deferring to a previously
93+
registered handler must be allowed. A third option is passed to handlers, the
94+
function `next` which represents the previously registered handler.
95+
96+
For example:
97+
98+
```js
99+
import { registerHandler } from "ember-debug/deprecations";
100+
101+
registerHandler(function firstDeprecationHandler(message, options, next) {
102+
console.warn(message);
103+
});
104+
105+
registerHandler(function secondDeprecationHandler(message, options, next) {
106+
if (options.until === "2.4.0") {
107+
throw new Error(message);
108+
}
109+
next(...arguments);
110+
});
111+
```
112+
113+
The first registed handler will receive Ember's default behavior as `next`.
114+
115+
##### new assertions for deprecate and warn
116+
117+
Ember's APIs for deprecation and warning do not currently require any information
118+
beyond a message. It is proposed that deprecations be **required** to pass
119+
the following information:
120+
121+
* Message
122+
* Test
123+
* Canonical id (with a format of `package-name.some-id`)
124+
* Release when this deprecation will be stripped
125+
126+
For example:
127+
128+
```
129+
import Ember from "ember";
130+
131+
Ember.deprecate("Some message", false, {
132+
id: 'ember-routing.query-params',
133+
until: '3.0.0'
134+
});
135+
```
136+
137+
If this information is not present and assertion will be made.
138+
139+
Warnings likewise will be required to pass a canonical id:
140+
141+
```
142+
import Ember from "ember";
143+
144+
Ember.warn("Some warning", {id: 'ember-debug.something'});
145+
```
146+
147+
##### default handlers
148+
149+
The default handler for deprecation should be quite simple, and mirrors current
150+
behavior:
151+
152+
```js
153+
function defaultDeprecationHandler(message, options) {
154+
if (Ember.ENV.RAISE_ON_DEPRECATION) {
155+
throw new Error(format(message, options));
156+
} else {
157+
console.log(format(message, options));
158+
}
159+
}
160+
```
161+
162+
The default handler for warnings would be simple `console.log`.
163+
164+
# Drawbacks
165+
166+
By not providing a robust log-level API, we are punting complexity to the
167+
consumer of this API. For a low-level tooling API such as this one, it seems
168+
and appropriate tradeoff.
169+
170+
# Alternatives
171+
172+
Each app can stub out `deprecate` and `warn`.
173+
174+
# Unresolved questions
175+
176+
`RAISE_ON_DEPRECATION` could be considered deprecated with this new API.

0 commit comments

Comments
 (0)