Skip to content

Commit 5727b3c

Browse files
committed
Pretty URL
1 parent 0d6a291 commit 5727b3c

3 files changed

Lines changed: 79 additions & 4 deletions

File tree

lib/src/compiler/utils.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,25 @@ export function handleLogEvent(
174174
span: span!,
175175
});
176176
} else {
177+
const url = event.span?.url;
178+
if (url) {
179+
const index = formatted.indexOf(url);
180+
if (index !== -1) {
181+
const replacement = utils.prettyUrl(url);
182+
if (url !== replacement) {
183+
formatted =
184+
formatted.slice(0, index) +
185+
replacement +
186+
formatted.slice(index + url.length);
187+
}
188+
}
189+
}
177190
console.error(formatted);
178191
}
179192
} else {
193+
let stack = event.stackTrace;
194+
if (stack && options?.legacy) stack = removeLegacyImporter(stack);
195+
180196
if (options?.logger?.warn) {
181197
const params: (
182198
| {
@@ -192,14 +208,13 @@ export function handleLogEvent(
192208
: {deprecation: false};
193209
if (span) params.span = span;
194210

195-
const stack = event.stackTrace;
196211
if (stack) {
197-
params.stack = options?.legacy ? removeLegacyImporter(stack) : stack;
212+
params.stack = stack;
198213
}
199214

200215
options.logger.warn(message, params);
201216
} else {
202-
console.error(formatted);
217+
console.error(utils.prettyFormatted(formatted, stack));
203218
}
204219
}
205220
}

lib/src/exception.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import * as proto from './vendor/embedded_sass_pb';
66
import {Exception as SassException, SourceSpan} from './vendor/sass';
77
import {deprotofySourceSpan} from './deprotofy-span';
8+
import {prettyFormatted} from './utils';
89

910
export class Exception extends Error implements SassException {
1011
readonly sassMessage: string;
1112
readonly sassStack: string;
1213
readonly span: SourceSpan;
1314

1415
constructor(failure: proto.OutboundMessage_CompileResponse_CompileFailure) {
15-
super(failure.formatted);
16+
super(prettyFormatted(failure.formatted, failure.stackTrace));
1617

1718
this.sassMessage = failure.message;
1819
this.sassStack = failure.stackTrace;

lib/src/utils.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,65 @@ export function fileUrlToPathCrossPlatform(fileUrl: url.URL | string): string {
124124
return /^\/[A-Za-z]:\//.test(path) ? path.substring(1) : path;
125125
}
126126

127+
/**
128+
* Returns a pretty URL similar to Dart's `path.prettyUri`.
129+
*/
130+
export function prettyUrl(url: string): string {
131+
if (!url.startsWith('file:')) return url;
132+
133+
const absolutePath = fileUrlToPathCrossPlatform(url);
134+
const relativePath = p.relative(process.cwd(), absolutePath);
135+
return relativePath.split(p.sep).length > absolutePath.split(p.sep).length
136+
? absolutePath
137+
: relativePath;
138+
}
139+
140+
/**
141+
* Reformat URLs in formatted text from the embedded compiler.
142+
*/
143+
export function prettyFormatted(formatted: string, stack: string): string {
144+
let longest = 0;
145+
146+
const frames = stack
147+
.split('\n')
148+
.filter(frame => frame !== '')
149+
.map(frame => {
150+
let [location, member] = frame.split(/ +/, 2);
151+
let [url, lineColumn] = location.split(' ', 2);
152+
153+
url = prettyUrl(url);
154+
location = lineColumn === undefined ? url : `${url} ${lineColumn}`;
155+
156+
if (location.length > longest) {
157+
longest = location.length;
158+
}
159+
return {
160+
frame,
161+
location,
162+
member,
163+
};
164+
});
165+
166+
let offset = formatted.length;
167+
168+
frames.reverse().forEach(({frame, location, member}) => {
169+
const index = formatted.lastIndexOf(frame, offset);
170+
if (index !== -1) {
171+
offset = index;
172+
173+
const replacement = `${location.padEnd(longest)} ${member}`;
174+
if (frame !== replacement) {
175+
formatted =
176+
formatted.slice(0, index) +
177+
replacement +
178+
formatted.slice(index + frame.length);
179+
}
180+
}
181+
});
182+
183+
return formatted;
184+
}
185+
127186
/** Returns `path` without an extension, if it had one. */
128187
export function withoutExtension(path: string): string {
129188
const extension = p.extname(path);

0 commit comments

Comments
 (0)